Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
75.89% covered (success)
75.89%
2634 / 3471
54.76% covered (warning)
54.76%
23 / 42
CRAP
0.00% covered (danger)
0.00%
0 / 1
AppController
75.89% covered (success)
75.89%
2634 / 3471
54.76% covered (warning)
54.76%
23 / 42
17592.15
0.00% covered (danger)
0.00%
0 / 1
 beforeFilter
20.50% covered (danger)
20.50%
165 / 805
0.00% covered (danger)
0.00%
0 / 1
77611.04
 setLocalization
88.32% covered (success)
88.32%
121 / 137
0.00% covered (danger)
0.00%
0 / 1
130.63
 redirectUsingIpLang
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
42
 redirect
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 1
702
 setConfigLanguage
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
1 / 1
10
 jpyOnlyPage
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
1 / 1
13
 checkIfAllowed
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
6
 getTimezoneData
94.23% covered (success)
94.23%
49 / 52
0.00% covered (danger)
0.00%
0 / 1
15.04
 chargePayPalPaymentReceivable
94.02% covered (success)
94.02%
283 / 301
0.00% covered (danger)
0.00%
0 / 1
65.90
 chargePaymentReceivable
94.03% covered (success)
94.03%
63 / 67
0.00% covered (danger)
0.00%
0 / 1
14.04
 wpChargePaymentReceivable
96.63% covered (success)
96.63%
86 / 89
0.00% covered (danger)
0.00%
0 / 1
17
 setSeoLocalizeUrl
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 getCustomCurrencyCode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
5
 getPremiumPlanPrice
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
5
 checkStasapuDomain
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
5
 disablePageForSapuri
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
8
 blockWithdrawnSapuriToS
89.47% covered (success)
89.47%
17 / 19
0.00% covered (danger)
0.00%
0 / 1
11.14
 createEnglishHubCookie
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
10
 checkControllerActionExist
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
5
 checkIfSNSShare
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
7
 setUpAppreciationSelectionModalElement
100.00% covered (success)
100.00%
56 / 56
100.00% covered (success)
100.00%
1 / 1
24
 sendTeacherAppreciation
100.00% covered (success)
100.00%
39 / 39
100.00% covered (success)
100.00%
1 / 1
14
 isLocalizeDirValid
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 chargeAfteePaymentReceivable
96.13% covered (success)
96.13%
298 / 310
0.00% covered (danger)
0.00%
0 / 1
63
 checkAfteeSupported
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
1 / 1
25
 queryGuideControl
100.00% covered (success)
100.00%
54 / 54
100.00% covered (success)
100.00%
1 / 1
4
 queryLineHoverControl
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
1 / 1
3
 NCPlusPositionUrlScheme
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 checkLitePlanSupported
100.00% covered (success)
100.00%
35 / 35
100.00% covered (success)
100.00%
1 / 1
27
 resetPresetTextbook
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
1 / 1
4
 setPaypalUser
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
6
 checkStripeSupported
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
1 / 1
31
 processChildReceivablePayment
95.31% covered (success)
95.31%
122 / 128
0.00% covered (danger)
0.00%
0 / 1
20
 processChildPaypalPayment
95.18% covered (success)
95.18%
217 / 228
0.00% covered (danger)
0.00%
0 / 1
22
 processChildAfteePayment
96.43% covered (success)
96.43%
216 / 224
0.00% covered (danger)
0.00%
0 / 1
28
 processParentReceivablePayment
95.28% covered (success)
95.28%
121 / 127
0.00% covered (danger)
0.00%
0 / 1
19
 processParentPaypalPayment
95.98% covered (success)
95.98%
215 / 224
0.00% covered (danger)
0.00%
0 / 1
22
 savePaypalFailedSettlement
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
5
 processParentAfteePayment
94.59% covered (success)
94.59%
210 / 222
0.00% covered (danger)
0.00%
0 / 1
24.09
 checkCompanyIPForSMS
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
6
 setPerMonthSymbol
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
20
 corporateIpRestrictionLogout
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Application level Controller
4 *
5 * This file is application-wide controller file. You can put all
6 * application-wide controller-related methods here.
7 *
8 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
9 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10 *
11 * Licensed under The MIT License
12 * For full copyright and license information, please see the LICENSE.txt
13 * Redistributions of files must retain the above copyright notice.
14 *
15 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
16 * @link          http://cakephp.org CakePHP(tm) Project
17 * @package       app.Controller
18 * @since         CakePHP(tm) v 0.2.9
19 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
20 */
21
22App::uses('Controller', 'Controller');
23
24/**
25 * Application Controller
26 *
27 * Add your application-wide methods in the class below, your controllers
28 * will inherit them.
29 *
30 * @package        app.Controller
31 * @link        http://book.cakephp.org/2.0/en/controllers.html#the-app-controller
32 */
33class AppController extends Controller {
34
35    /**
36     * セッションコンポーネント
37     *
38     * @var SessionComponent
39     */
40    var $Session;
41    public $uses = array(
42        'User',
43        'Notification',
44        'DefineMaster',
45        'CountryCode',
46        'LessonOnairsLog',
47        'LessonConnectionSpeedDetail',
48        'CountryCode',
49        'HeyNCUser',
50        'GuideNavigationbarCategory',
51        'GuideNavigationbarContent',
52        'GuideNavigationbarAuthControl',
53        'GuideNavigationbarMembershipControl',
54        'GuideNavigationbarCurrencyControl',
55        'GuideNavigationbarBrowserLangControl',
56        'CorporateActivationManagement',
57        'UsersDetail',
58        'CompCodeUsage',
59        'Corporate',
60        'RyugakuSchoolLineSetting',
61        'TeacherCoinBox',
62        'InhouseIp',
63        'Timezone'
64    );
65    public $helpers = array('Localize');
66    public $ext = '.php';
67    public $sharedUserData = false;
68    public $components = array(
69        'Paginator',
70        'RequestHandler',
71        'DebugKit.Toolbar',
72        'Session',
73        'Cookie',
74        'Auth' => array(
75            'authenticate'=>array(
76                'Form'=>array(
77                    'fields'=>array('username'=>'email','password'=>'password')
78                )
79            ),
80            'loginRedirect' => array('controller' => 'home', 'action' => 'index'),
81            'logoutRedirect' => array('controller' => 'login', 'action' => 'index'),
82            'loginAction' => '/login',
83            'authError' => '再度ログインしなおしてください。',
84            'loginError' => 'メールアドレス、またはパスワードに誤りがあります。'
85        )
86    );
87    public $slackChannel = "";
88    public $mySlack = NULL;
89    private $a8Url = ""; 
90    private $affiliateUrl = ""; // Affiliate url callback
91    public $timeDiff = 0; // default
92    public $timeDiffSecond = 0;
93    public $displayTime = 0;
94    public $utcOffset = "09:00";// default tokyo
95    public $lang_iso = "";
96    public $parentId = NULL;
97    public $localizeDir;
98    public $baseUrl;
99    public $clpip; // NC-7360 : corporate light plan individual payment
100    public $allowedCoupon = false; 
101    public $studySapuriId = NULL; // NC-7922, Stasap toC/toB(old)
102    public $allowedCurrencies;
103    public $isPayPalUser = false;
104    public $isAfteeUser = false;
105    public $mobAppUserData;
106    public $isSNSShare;
107    public $isSNSShareOverseas;
108    public $studentLessonPriorityTimeDelayInSeconds = 0;
109    public $isStudySapuriTosUser = false; # -stasap toS(new) members, flagging
110    public $isStudySapuriUser = false; # -either Stasap toC/toB/toS(new) members, flagging
111    public $isTemporaryPassword = false;
112    public $localizeIPLang;
113    public $isIndividualCorp = false;
114    public $corpStandardPremiumPaymentPlans = [];
115    public $isStripeUser = false;
116    public $isStripeAppleUser = false;
117    public $isStripeGoogleUser = false;
118    public $isSetLineHoverSetting = false;
119    public $userMembershipType = null;
120    public $isWithdrawn = false;
121
122    public function beforeFilter() {
123
124        $this->Cookie->httpOnly = true;
125        /*Configure Path*/
126        App::build(array(
127            'Model'=>array(
128                ROOT.'/lib/Model/Base/',
129                ROOT.'/lib/Model/',
130                ROOT.'/lib/Model/',
131                ROOT.'/lib/Model/Form/'),
132            'Lib'=>array(
133                ROOT.'/lib/Lib/'
134            ),
135            'Vendor'=>array(
136                ROOT.'/lib/Vendor/'
137            )
138        ));
139        
140        /*Autoload Model*/
141        App::import('Model',array('CommonTable'));
142        App::import('Model',array('CourseMaster'));
143        App::import('Model',array('DefineMaster'));
144
145        /*Autoload Lib*/
146        App::uses('myTools','Lib');
147        App::uses('myMailer','Lib');
148        App::uses('myError','Lib');
149        App::uses('myTranslator','Lib');
150        App::uses('myMemcached', 'Lib');
151        App::uses('textbookTemplate', 'Lib');
152        App::uses('mySlack','Lib');
153        App::uses('wpPaymentService','Lib');
154        App::uses('CommonCache','Lib');
155        App::uses('OfficeAccounting','Lib');
156        App::uses('LineMessageBot', 'Lib'); // NJ-37740
157
158        /*Autoload table class*/
159        spl_autoload_register(function($class){
160            $classFile1 = ROOT.'/lib/Model/'.$class.'.php';
161            $classFile2 = ROOT.'/lib/Model/Form/'.$class.'.php';
162            if(is_file($classFile1)){ require_once($classFile1); }
163            if(is_file($classFile2)){ require_once($classFile2); }
164        });
165
166        //*NC-4284: if url has user remove user and redirect
167        $webUrl = $_SERVER['REQUEST_URI'];
168        $this->parseUrl = parse_url($webUrl);
169        $segment = explode('/', $webUrl);
170        $firstSegment = isset($segment[1])? $segment[1]:'';
171        $secondSegment = isset($segment[2])? $segment[2]:'';
172
173        if (!$this->request->is('post') && !$this->request->is('ajax')) {
174            if ($this->Auth->loggedIn()) {
175                // if (!$this->RequestHandler->isMobile() && !$this->isLocalizeDirValid($this->Cookie->read('localizeDir'))) {
176                //     $this->Session->destroy();
177                //     $past = time() - 3600;
178                //     foreach ( $_COOKIE as $key => $value )
179                //     {    
180                //         setcookie( $key, $value, $past, '/' );
181                //     }
182                // }
183            }
184
185            if ($firstSegment == 'user') {
186                # added localize URL
187                if($secondSegment == 'ja') {
188                    $getNewUrl = str_replace("/user/ja/", "", $webUrl);
189                } else {
190                    $getNewUrl = str_replace("/user/", "", $webUrl);
191                }
192                $url = myTools::getUrl() ."/". $getNewUrl;
193
194                $this->log("Redirect : " . $url , "debug");
195                return $this->redirect($url, 301);
196            }
197
198            # added localize URL
199            if ($firstSegment == 'ja') {
200                if ($webUrl == "/ja" && $segment[2] == '') {
201                    $url = myTools::getUrl();
202                } else {
203                    $getNewUrl = str_replace("/ja/", "", $webUrl);
204                    $url = myTools::getUrl() ."/". $getNewUrl;
205                }
206
207                $this->log("Redirect : " . $url , "debug");
208                return $this->redirect($url, 301);
209            }
210        }
211
212        /*Autoload table class*/
213        spl_autoload_register(function($class){
214            $classFile1 = ROOT.'/lib/Model/'.$class.'.php';
215            $classFile2 = ROOT.'/lib/Model/Form/'.$class.'.php';
216            if(is_file($classFile1)){ require_once($classFile1); }
217            if(is_file($classFile2)){ require_once($classFile2); }
218        });
219        
220        // - if maintenance check
221        if (strtolower(trim($this->request->params['controller'])) == "maintenance-check.html") {
222            return false;
223        }
224        
225        //set language to null to avoid overwriting
226        Configure::write('Config.language', NULL);
227
228        /*Autoload Lib*/
229        Configure::load('my');
230        Configure::load('const');
231
232        if($this->Auth->loggedIn()){
233            $user = $this->Auth->user();
234            $localLang = isset($this->request->data['localizeDir']) ? $this->request->data('localizeDir') : $firstSegment;
235            $params = array(
236                'currency_code' => $user['currency_code'] ?? null,
237                'created' => $user['created'] ?? null,
238                'language' => $localLang
239            );
240
241            if($this->User->languageAccessControlCheck($params) && (!in_array($firstSegment, ['access_control', 'login', 'logout']) && !in_array($secondSegment, ['access_control', 'login', 'logout']))){
242                if(in_array($firstSegment, ['zh-tw', 'zh-cn', 'vi'])){
243                    $latestUrl = preg_replace('/\/(zh-tw|zh-cn|vi)\//', '/', $webUrl);
244                    if(!empty($secondSegment)) {
245                        $this->Session->write("latestAccessUrl" , $latestUrl);
246                    } else {
247                        $this->Session->write("latestAccessUrl" , '/');
248                    }
249                }
250                $url = myTools::getUrl() . "/access_control";
251                return $this->redirect($url, 302);
252            }
253        }
254
255        // - memcache declaration
256        $memcached = new myMemcached();
257        
258        //remove trailing slashes only if not post and not ajax
259        if (!$this->request->is('post') && !$this->request->is('ajax')) {
260            $currURLSTR = $this->here;
261            if (substr($currURLSTR, -1) == '/' && $currURLSTR != '/user/') {
262
263                $currURLSTR = rtrim($currURLSTR, '/');
264                //check if theres a GET data to be append
265                if (!empty($_SERVER['QUERY_STRING'])) {
266                    $currURLSTR = $currURLSTR . '?' . $_SERVER['QUERY_STRING'];
267                }
268
269                // if (!$this->RequestHandler->isMobile() && !$this->isLocalizeDirValid($this->Cookie->read('localizeDir'))) {
270                //     $this->log("redirect_debug -> invalid localizeDirectory" . json_encode($this->Cookie->read('localizeDir')) , "debug");
271                //     return $this->redirect('/');
272                // }
273                
274                return $this->redirect(myTools::getUrl() . $currURLSTR, 301);
275            }
276        }
277
278        if(isset($this->params->params['controller']) &&
279            in_array($this->params->params['controller'], array('register', 'spRegister', 'forgot', 'sp')) &&
280            isset($this->params->params['action']) &&
281            in_array($this->params->params['action'], array('activate_email', 'activate', 'forgotactivate')) &&
282            isset($this->params->params['code'])
283        ) {
284
285            if($this->RequestHandler->isMobile() == false && $this->params->params['controller'] == 'spRegister' && $this->params->params['action'] === 'activate') {
286                return $this->redirect('/register/activate-email/' . $this->params->params['code']);
287            }
288        }
289
290        $paymentPlans = Configure::read('payment_plans');
291        $this->corpStandardPremiumPaymentPlans = [
292            $paymentPlans['corporate_standard_plan'],
293            $paymentPlans['corporate_standard_card_plan'],
294            $paymentPlans['corporate_standard_individual_plan'],
295            $paymentPlans['corporate_premium_plan'],
296            $paymentPlans['corporate_premium_card_plan'],
297            $paymentPlans['corporate_premium_individual_plan']
298        ];
299        $this->set('corpStandardPremiumPaymentPlans', $this->corpStandardPremiumPaymentPlans);
300        $this->set('userCDNPath', Configure::read('user.cdn_path_webroot'));
301        $this->set('userCDNPathV2', Configure::read('user.cdn_path_webroot_v2'));
302        
303        /*Security Check*/
304        $user = $this->Auth->user();
305
306        $skipBeforeFilterActions = Configure::read('skipped_actions_before_filter');  // NJ-47850: Define the actions to skip the beforeFilter
307        // NJ-47850: Get the current controller and action
308        $currentController = $this->name;
309        $currentAction = $this->action;
310        
311        // Check if the current action should skip the beforeFilter
312        if (isset($skipBeforeFilterActions[$currentController]) && in_array($currentAction, $skipBeforeFilterActions[$currentController])) {
313            $datetime = time();
314            
315            if(isset($user) && !empty($user['id'])){
316                $memcachedTimeDiff = $memcached->get('user-timediff-' . $user['id']);
317                    $this->log("[NJ-47850] AppController.php L#".__LINE__." -- user-timediff memcached data: " . json_encode($memcachedTimeDiff), 'error');
318                if (isset($memcachedTimeDiff['timeDiff']) || isset($memcachedTimeDiff['utc'])) {
319                    $this->timeDiff = isset($memcachedTimeDiff['timeDiff']) && is_numeric($memcachedTimeDiff['timeDiff']) ? $memcachedTimeDiff['timeDiff'] : 0;
320                    $this->utcOffset = $memcachedTimeDiff['utc'];
321                    $this->displayTime = $this->Timezone->getUserTime(array('timeDiff' => $this->timeDiff));
322                }else{
323                    $this->displayTime = $datetime;
324                }
325            }else{
326                $this->displayTime = $datetime;
327            }
328            
329            return false;
330        }
331        // end NJ-47850
332        
333        /*meta title*/
334        $meta = Configure::read('my.meta.'.strtolower($this->name));
335        if (!$meta) {
336            $meta = Configure::read('my.meta.'.strtolower($this->action));
337        }
338        if (!$meta) {
339            $meta = Configure::read('my.meta.'.strtolower($this->name).'-'.strtolower($this->action));
340        }
341        if (!empty($meta['title'])) {
342            $this->set('title_for_layout',$meta['title']);
343        }
344        if (!empty($meta['keywords'])) {
345            $this->set('meta_keywords',$meta['keywords']);
346        }
347        if (!empty($meta['description'])) {
348            $this->set('meta_description',$meta['description']);
349        }
350
351        if (!$this->Auth->loggedIn() && $this->Cookie->read('rememberMe') && !$this->RequestHandler->isMobile()) {
352            $cookie = $this->Cookie->read('rememberMe');
353            $this->User->openDBReplica();
354            $this->User->recursive = -1;
355            $data = $this->User->findByEmailAndPassword(myTools::decode($cookie['ae']),myTools::decode($cookie['ap']));
356            $this->User->closeDBReplica();
357            if ($data) {
358                $this->Auth->login($data['User']);
359                if (!$this->RequestHandler->isMobile()) {
360                    return $this->redirect(myTools::getUrl() . '/user/mypage');
361                }
362            }
363        }
364
365        $hideA8 = false;
366        $hideEngHub = false;
367        $engHubCookieIndexStr = null;
368        if (!$this->Auth->loggedIn()) {
369            $cookieTime = Configure::read("cookieTime");            
370            if (isset($this->request->query['cc']) && $this->request->query['cc'] != '') {
371                //extract prefix from cc
372                $cc = explode('_', $this->request->query['cc']);
373                $prefix = isset($cc[0]) ? trim(strtolower($cc[0])) : false;
374                if ($prefix == 'fr') {
375                    // NJ-6146 Check campaign code is FR -> auto redirect to FR_CP
376                    if (isset($cc[1]) && strtolower($cc[1]) != 'cp') {
377                        $query = $this->request->query;
378                        $cc[0] = 'FR_CP';
379                        $query['cc'] = implode('_', $cc);
380                        $query_string = http_build_query($query);
381
382                        $url = $this->here . '?' . $query_string;
383
384                        $this->log("Redirect : " . $url , "debug");
385
386                        return $this->redirect(myTools::getUrl() . $url, 301);
387                    }
388                    // log
389                    $this->log("[REFERRAL] saving referral code '".$this->request->query['cc']."'' to Cookie! ", "debug");    
390                }
391                
392                $this->Cookie->write('campaign_code', $this->request->query['cc'], true, $cookieTime);
393            }
394            
395            //save cookie a8 identification
396            if (isset($this->request->query['a8']) && !empty($this->request->query['a8'])) {
397                $this->Cookie->write('a8_id', $this->request->query['a8'], true, $cookieTime);
398            }
399
400            // NC-8916 - Generate english hub cookie
401            $engHubCookieIndexStr = $this->createEnglishHubCookie();
402
403            // NJ-26035 - save cookie for google cloud id 
404            if (
405                (isset($this->request->query['gclid']) && !empty($this->request->query['gclid']))
406            ) {
407            
408                $googleCloudCookie = $this->Cookie->read('gclid');
409
410                // - save the cookie if not yet saved
411                if (!$googleCloudCookie) {
412                    $this->Cookie->write('gclid', $this->request->query['gclid'], true, $cookieTime);
413                }
414
415                // - save the cookie when the saved cookie is not the same as the params google cloud id
416                if (
417                    $googleCloudCookie && 
418                    $googleCloudCookie != $this->request->query['gclid']
419                ) {
420                    $this->Cookie->write('gclid', $this->request->query['gclid'], true, $cookieTime);
421                }
422            }
423
424            //NJ-63077 - save cookie for facebook cloud id and tiktok cloud id
425            if (
426                (isset($this->request->query['fbclid']) && !empty($this->request->query['fbclid'])) || (isset($this->request->query['ttclid']) && !empty($this->request->query['ttclid']))
427            ) {
428            
429                $facebookCloudCookie = $this->Cookie->read('fbclid');
430                $tiktokCloudCookie = $this->Cookie->read('ttclid');
431
432                // - save the cookie if not yet saved
433                if (!$facebookCloudCookie) {
434                    $this->Cookie->write('fbclid', $this->request->query['fbclid'], true, $cookieTime);
435                }
436                
437                if (!$tiktokCloudCookie) {
438                    $this->Cookie->write('ttclid', $this->request->query['ttclid'], true, $cookieTime);
439                }
440
441                // - save the cookie when the saved cookie is not the same as the params google cloud id
442                if (
443                    $facebookCloudCookie && 
444                    $facebookCloudCookie != $this->request->query['fbclid']
445                ) {
446                    $this->Cookie->write('fbclid', $this->request->query['fbclid'], true, $cookieTime);
447                }
448
449                if (
450                    $tiktokCloudCookie && 
451                    $tiktokCloudCookie != $this->request->query['ttclid']
452                ) {
453                    $this->Cookie->write('ttclid', $this->request->query['ttclid'], true, $cookieTime);
454                }
455            }
456            
457            //NJ-63077 - delete other cloud id cookies if one is set
458            if (!empty($this->request->query['gclid'])) {
459                $this->Cookie->delete('fbclid');
460                $this->Cookie->delete('ttclid');
461            } elseif (!empty($this->request->query['fbclid'])) {
462                $this->Cookie->delete('gclid');
463                $this->Cookie->delete('ttclid');
464            } elseif (!empty($this->request->query['ttclid'])) {
465                $this->Cookie->delete('gclid');
466                $this->Cookie->delete('fbclid');
467            }
468
469        } else {
470            //check if complimentary user
471            $complimentary_code = $this->Auth->user('complimentary_code');
472            if (!empty($complimentary_code)) {
473                $hideA8 = true;
474                $hideEngHub = true;
475            }
476        }
477
478        //check a8 exist
479        if ($this->Cookie->check('a8_id') && !$hideA8) {
480            $encodeURL = myTools::getUrl() . '/api/users/purchase_done?a8=' . $this->Cookie->read('a8_id') . '&api_token={partner_parameters}';
481            $this->a8Url = 'event_callback_a967je=' . urlencode($encodeURL);
482            $this->affiliateUrl = $this->a8Url;
483        }
484
485
486        // NC-8916 : check english hub affiliate tracking
487        $ehubCookieIndex = Configure::read('english_hub_affiliate_param.p');
488        if ( $this->Cookie->check($engHubCookieIndexStr) && !$hideEngHub ) {
489            $setcid = $this->Cookie->read($engHubCookieIndexStr);
490            $encodeURL = myTools::getUrl() . '/api/users/purchase_done?cid=' . $setcid . '&api_token={partner_parameters}';
491            $this->affiliateUrl = 'event_callback_a967je=' . urlencode($encodeURL);
492        }
493
494        $this->set('affiliateUrl', $this->affiliateUrl);
495        $this->set('a8Url', $this->a8Url);
496        $this->set('a8_id', $this->Cookie->read('a8_id'));
497
498        //if cookie is not set then detect device then set cookie
499        if(!isset($_COOKIE['viewMode'])) {
500            $device = myTools::getDevice();
501            if ($device == 2 || $device == 3 || $device == 4) {
502                setcookie('viewMode', 'sp', 0, '/');
503            } else {
504                setcookie('viewMode', 'pc', 0, '/');
505            }
506        }
507
508        //NC-4772 [Asia deployment] [Mobapp] 
509        $parentData = $this->User->setConfigLanguage($this->request->query);
510        $this->set('current_lang', $parentData['current_lang']);
511        $this->set('restriction', $parentData['restriction']);
512
513        $this->set('ver', Configure::read('user.version'));
514
515        //get parent_id for family validation
516        $this->parentId = isset($parentData['User']['parent_id']) ? $parentData['User']['parent_id'] : NULL;
517
518        // check if from SNS share        
519        $this->isSNSShare = $this->checkIfSNSShare();
520        $this->isSNSShareOverseas = (isset($_GET["nc_sns_is_overseas"]) && $_GET["nc_sns_is_overseas"] == 1) ? true : false;
521        $this->set('isSNSShare', $this->isSNSShare);
522
523        # NC-7196: LOCALIZE URL
524        $this->localizeDir = Configure::read('default.localization');
525        $this->setLocalization();
526        $this->setSeoLocalizeUrl();
527
528        # NJ-18262 : Guide Control
529        $redis = new myRedis();
530        $guideControlCached = $redis->get("dynamic_global_guide_control");
531        $lineGuideControlCached = $redis->get("dynamic_line_hover_guide_control");
532
533        if (!$guideControlCached){
534            $this->queryGuideControl();
535        } else {
536            $guideNavigationbarCategory = json_decode($redis->get("dynamic_global_guide_control"),true);
537            $this->set('GuideNavigationbarCategory', $guideNavigationbarCategory);
538        }
539
540        if (!$this->isSetLineHoverSetting) {
541            $this->isSetLineHoverSetting = true;
542            $this->queryLineHoverControl();
543        }
544
545        // check if url is from payment kickback "bypass maintenance redirection for zeus and worldpay"
546        $isPayment = in_array(strtolower($this->params['action']), ['zeuspay', 'getwppaymentresult', 'getafteepaymentresult','school_zeuspay','school_zeuspay_bank', 'stripepay', 'stripepay_manual']);
547
548        // - check if maintenance
549        if (!myTools::checkCompanyIP($_SERVER['REMOTE_ADDR']) && !$isPayment) {
550            $maintenance = MaintenanceTable::getMaintenance();
551            if ($maintenance) {
552                // CHECK IF ACCESS TYPE NOT SEO CRAWLER
553                if ( myTools::isCrawler() === FALSE ) {
554                    $controller = strtolower($this->params['controller']);
555                    $action = strtolower($this->params['action']);
556                    if ( $this->Auth->loggedIn() ) {
557                        $this->log('[NJ-65075] AppController.php L#'.__LINE__.' -- '.json_encode(array('request_data' => $this->request, 'user_agent' => $_SERVER['HTTP_USER_AGENT'])), 'error');
558                        $this->Auth->logout();
559                    }
560
561                    if($controller != 'maintenance' && !in_array($action, array('regular', 'checkmaintenance'))) {
562                        if (
563                            strpos($_SERVER['REQUEST_URI'], "/ko") !== false ||
564                            strpos($_SERVER['REQUEST_URI'], "/zh-tw")  !== false ||
565                            strpos($_SERVER['REQUEST_URI'], "/vi")  !== false
566                        ) {
567                            return $this->redirect('/../maintenance/regular');
568                        }
569                        return $this->redirect('/maintenance/regular');
570                    }
571                }
572            }
573        }
574        
575        //add link to sp
576        $device = myTools::getDevice();
577        $showLink = ($device == 2 || $device == 3 || $device == 4)? 1: 0;
578        $this->set('showLink', $showLink);
579        
580        // check current controller
581        $currentPageController = isset($this->params['controller']) ? trim(strtolower($this->params['controller'])) : null;
582        $userData = false;
583        
584        // if logged in
585        if ($this->Auth->loggedIn()) {
586            # get user data
587            $this->User->openDBReplica();
588            $this->User->virtualFields['complimentary_code'] = "(SELECT Code.code FROM comp_code_usage AS Code WHERE Code.user_id = User.id AND Code.active_flg = 1 LIMIT 1)";
589            $userData = $this->User->find('first', array(
590                'fields' => [
591                    'User.*',
592                    'UsersExtend.*',
593                    'UsersDetail.*',
594                    'CorporateActivationManagement.*'
595                ],
596                'joins' => [
597                    [
598                        'table' => 'users_extend',
599                        'alias' => 'UsersExtend',
600                        'type' => 'LEFT',
601                        'conditions' => 'UsersExtend.user_id = User.id'
602                    ],
603                    [
604                        'table' => 'corporate_activation_managements',
605                        'alias' => 'CorporateActivationManagement',
606                        'type'    => 'LEFT',
607                        'conditions'    => 'User.id = CorporateActivationManagement.user_id'
608                    ],
609                    [
610                        'table' => 'users_detail',
611                        'alias' => 'UsersDetail',
612                        'type' => 'LEFT',
613                        'conditions' => 'UsersDetail.user_id = User.id'
614                    ]
615                ],
616                'recursive' => -1,
617                'conditions' => array('User.id' => $this->Auth->user('id'))
618            ));
619            $this->User->closeDBReplica();
620
621            $userData['User']['payment_plan_id'] ??= '';
622            $userData['User']['corporate_id'] ??= '';
623            $userData['User']['corporate_individual_payment_flg'] ??= '';
624
625            $this->isWithdrawn = (isset($userData['User']['status']) && $userData['User']['status'] == 9) ? true : false;
626            
627            // redirect to change pass if stasapu tos user and temporary password not change.
628            if (
629                !$this->RequestHandler->isMobile() &&
630                strtolower($this->params->params['action']) != 'changefirstpass' &&
631                strtolower($this->params->params['action']) != 'logout' &&
632                isset($userData['UsersExtend']['temporary_pw_flg']) &&
633                $userData['UsersExtend']['temporary_pw_flg']
634            ) {
635                return $this->redirect('/account/change-first-pass');
636            } elseif(
637                // NJ-23929: redirect to change pass if user is registered through corporate
638                !$this->RequestHandler->isMobile() &&
639                strtolower($this->params->params['action']) != 'changefirstpass' &&
640                strtolower($this->params->params['action']) != 'logout' &&
641                isset($userData['CorporateActivationManagement']['temporary_pw_flg']) &&
642                $userData['CorporateActivationManagement']['temporary_pw_flg'] == 1
643            ){
644                return $this->redirect('/account/change-first-pass');
645            } elseif (
646                $this->RequestHandler->isMobile() &&
647                strtolower($this->params->params['controller']) != 'account' &&
648                strtolower($this->params->params['controller']) != 'index' &&
649                strtolower($this->params->params['action']) != 'logout' &&
650                isset($userData['UsersExtend']['temporary_pw_flg']) &&
651                $userData['UsersExtend']['temporary_pw_flg']
652            ) {
653                return $this->redirect('/account');
654            }
655
656            $userObj = new UserTable($userData['User']);
657            $userObj->currency_code ??= '';
658            if ($this->request->params['controller'] === 'login' &&
659                ($this->request->params['action'] === 'index' || $this->request->params['action'] === 'logout')) {
660                return;
661            }
662
663            if (!$this->RequestHandler->isMobile() && in_array($userObj->corporate_id, Configure::read("blocked_corporate_member_types"))) {
664                $remoteAddress = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : "0.0.0.0";
665
666                if (!in_array($remoteAddress, Configure::read("corporate_allowed_ip"))) {
667
668                    $params = array(
669                        'message' => '特定法人で許可されていないIPアドレスからアクセスがありました。',
670                        'member_id' => $user['id'],
671                        'type' => 'IPアドレス:' . $remoteAddress,
672                    );
673
674                    $userObj->slackSoftbankNotice($params);
675
676                    return $this->corporateIpRestrictionLogout();
677                }
678            }
679
680            $this->allowedCoupon = $userObj->allowedMemberCoupon();
681
682            #NC-7922: update username fo studysapuri
683            if (isset($userData['User']['studysapuri_id']) && $userData['User']['studysapuri_id']) {
684                $userData['User']['nickname'] = str_replace("[Study Sapuri ENGLISH] ","", $userData['User']['nickname']);
685            }
686
687            if (
688                isset($userData['User']['card_company']) &&
689                (
690                    $userData['User']['card_company'] == Configure::read('card_company.paypal') ||
691                    isset($userData['User']['paypal_billing_agreement_id'])
692                )
693            ) {
694                $this->isPayPalUser = true;
695            } else if (
696                isset($userData['User']['card_company']) &&
697                (
698                    $userData['User']['card_company'] == Configure::read('card_company.aftee') || 
699                    (empty($userData['User']['card_company']) && $userData['User']['card_brand'] == 'AFTEE' && !empty($userData['User']['aftee_transaction_identifier']))
700                )
701            ) {
702                $this->isAfteeUser = true;
703            } else if (
704                in_array($userData['User']['card_company'], Configure::read('card_company.stripe')) || 
705                (!empty($userData['User']['stripe_customer_id']) && !empty($userData['User']['stripe_payment_identifier']))
706            ) {
707                $this->isStripeUser = true;
708
709                if ($userData['User']['card_company'] == Configure::read('card_company.stripe.apple')) {
710                    $this->isStripeAppleUser = true;
711                } elseif ($userData['User']['card_company'] == Configure::read('card_company.stripe.google')) {
712                    $this->isStripeGoogleUser = true;
713                }                
714            }
715
716            if (!empty($userData['User']['timezone_id'])) {
717                $this->loadModel('Timezone');
718                //get memcached timezone
719                $memcachedTimeDiff = $memcached->get('user-timediff-' . $userData['User']['id']);
720                if (!isset($memcachedTimeDiff['timeDiff']) || !isset($timeDiffData['utc'])) {
721                    $this->Timezone->openDBReplica();
722                    $timezone = $this->Timezone->find('first', array(
723                        'fields' => array('Timezone.continent_id', 'Timezone.city_eng'),
724                        'conditions' => array('Timezone.id' => $userData['User']['timezone_id'])
725                    ));
726                    $this->Timezone->closeDBReplica();
727                    $timeDiffData = array('success' => false);
728                    if ($timezone) {
729                        //get user time difference
730                        $timeDiffData = $this->Timezone->computeTimeDiff(array('continent_id' => $timezone['Timezone']['continent_id'], 'city' => $timezone['Timezone']['city_eng']));
731                    }
732                    if ($timeDiffData['success']) {
733                        $this->timeDiff = $timeDiffData['timeDiff'];
734                        $this->utcOffset = $timeDiffData['utc'];
735                     }
736
737                    //save to memcache
738                    $memcached->set(array(
739                        'key' => 'user-timediff-' . $userData['User']['id'],
740                        'value' => array(
741                            'timeDiff' => $this->timeDiff,
742                            'utc' => $this->utcOffset
743                        ),
744                        'expire' => 604800 //1 week
745                     ));
746                } else {
747                    //get memcached time difference
748                    $this->timeDiff = $memcachedTimeDiff['timeDiff'];
749                    $this->utcOffset = $memcachedTimeDiff['utc'];
750                }
751                //compute time difference in seconds
752                $this->timeDiffSecond = intval($this->timeDiff * 60);
753                //get user time
754                $this->displayTime = $this->Timezone->getUserTime(array('timeDiff' => $this->timeDiff));
755            } else {
756                //use server timezone Asia/Tokyo if timezone is not set
757                $this->displayTime = time();
758            }
759
760            // NC-7360 : Corporate Light Individual Payment
761            $corpType = myTools::getCoporateTypeUsingPaymentPlanId($userData['User']['payment_plan_id'] );
762            $this->clpip = ($userData['User']['corporate_id'] && $corpType == Configure::read("corporate_type.light") && $userData['User']['corporate_individual_payment_flg'] == 1);
763
764            // NC-7922
765            $this->studySapuriId = isset($userData['User']['studysapuri_id']) ? $userData['User']['studysapuri_id'] : NULL;
766            $this->isStudySapuriTosUser = !empty($userData['UsersExtend']['id']) ? true : false;
767            $this->isTemporaryPassword = $userData['UsersExtend']['temporary_pw_flg'] ?? '';
768            $this->defaultCameraSetting = (isset($userData['UsersDetail']['new_camera_flg']) && is_numeric($userData['UsersDetail']['new_camera_flg'])) ? $userData['UsersDetail']['new_camera_flg'] : 1;
769        } else {
770            //use system time if not yet login
771            $this->displayTime = time();
772
773            $apiToken = isset($this->request->query['token']) ? $this->request->query['token'] : null;
774            if (trim($apiToken) != null) {
775                $this->User->openDBReplica();
776                $appUserData = $this->User->find('first', array(
777                    'fields' => array(
778                        'User.id',
779                        'User.currency_code',
780                        'User.studysapuri_id',
781                        'User.corporate_id',
782                        'User.card_company',
783                        'User.paypal_billing_agreement_id',
784                        'UsersExtend.id',
785                        'User.aftee_transaction_identifier',
786                        'User.card_brand',
787                        'User.card_number',
788                        'User.paypal_payer_id',
789                        'User.paypal_payer_email',
790                        'User.stripe_customer_id',
791                        'User.stripe_payment_identifier',
792                        'User.payment_plan_id',
793                        'User.status',
794                    ),
795                    'joins' => [
796                        [
797                            'table' => 'users_extend',
798                            'alias' => 'UsersExtend',
799                            'type' => 'LEFT',
800                            'conditions' => 'UsersExtend.user_id = User.id'
801                        ]
802                    ],
803                    'conditions' => array('User.api_token' => $this->request->query['token']),
804                    'recursive' => -1,
805                ));
806                $this->User->closeDBReplica();
807
808                if ($appUserData) {
809                    // set sapuri id
810                    if (isset($appUserData['User']['studysapuri_id'])) {
811                        $this->studySapuriId = $appUserData['User']['studysapuri_id'];
812                    }
813
814                    if (!empty($appUserData['UsersExtend']['id'])) {
815                        $this->isStudySapuriTosUser = true;
816                    }
817
818                    // set isPayPalUser
819                    if (
820                        (isset($appUserData['User']['card_company']) && $appUserData['User']['card_company'] == Configure::read('card_company.paypal')) ||
821                        isset($appUserData['User']['paypal_billing_agreement_id'])
822                    ) {
823                        $this->isPayPalUser = true;
824                    }
825
826                    // set isAfteeUser
827                    if (
828                        (isset($appUserData['User']['card_company']) && $appUserData['User']['card_company'] == Configure::read('card_company.aftee')) ||
829                        (empty(isset($appUserData['User']['card_company'])) && isset($appUserData['User']['card_brand']) && isset($appUserData['User']['aftee_transaction_identifier']) && $appUserData['User']['card_brand'] == 'AFTEE' && !empty($appUserData['User']['aftee_transaction_identifier']))
830                    ) {
831                        $this->isAfteeUser = true;
832                    }
833
834                    // set isStripeUser 
835                    if (
836                        (isset($appUserData['User']['card_company']) && in_array($appUserData['User']['card_company'], Configure::read('card_company.stripe'))) || 
837                        (empty($appUserData['User']['card_company']) && isset($appUserData['User']['stripe_customer_id']) && isset($appUserData['User']['stripe_payment_identifier']) && !empty($appUserData['User']['stripe_customer_id']) && !empty($appUserData['User']['stripe_payment_identifier']))
838                    ) {
839                        $this->isStripeUser = true;
840                    
841                        if (isset($appUserData['User']['card_company'])) {
842                            if ($appUserData['User']['card_company'] == Configure::read('card_company.stripe.apple')) {
843                                $this->isStripeAppleUser = true;
844                            } elseif ($appUserData['User']['card_company'] == Configure::read('card_company.stripe.google')) {
845                                $this->isStripeGoogleUser = true;
846                            }
847                        }
848                    }
849
850                    $this->isWithdrawn = (isset($appUserData['User']['status']) && $appUserData['User']['status'] == 9) ? true : false;
851
852                    $this->mobAppUserData = $appUserData;
853                }
854            }
855        }
856
857        $this->set('isStripeUser', $this->isStripeUser);
858        $this->set('isStripeAppleUser', $this->isStripeAppleUser);
859        $this->set('isStripeGoogleUser', $this->isStripeGoogleUser);
860        $this->set('isPayPalUser', $this->isPayPalUser);
861        $this->set('isAfteeUser', $this->isAfteeUser);
862        
863        //NC-5125 iso_639_1 for meta tag
864        $this->lang_iso = $this->User->getLangIso($this->request->query);
865        $this->set('lang_iso', $this->lang_iso);
866
867        // header data
868        if (
869            $this->Auth->loggedIn() && 
870            $this->request->params['action'] != "callLessonAlertandStartButton" &&
871            !$this->request->is('ajax') &&
872            (
873                isset($this->params['controller']) && 
874                ($currentPageController != 'class' && $currentPageController != 'htmltextbook' && $currentPageController != 'cs' && !($currentPageController == 'account' && $this->request->params['action'] == 'index'))
875            ) &&
876            !(strpos($this->params->url, 'paypal/create-billing-agreement-token') !== false) &&
877            !(strpos($this->params->url, 'Payment/zeuspayGetChallenge') !== false) &&
878            !(strpos($this->params->url, 'faq') !== false) &&
879            !(strpos($this->params->url, 'entire_faq') !== false)
880        ) {
881            //load redis
882            App::uses('myRedis', 'Lib');
883            $redis = new myRedis();
884            
885            //set key
886            $key = 'ACTIVE_USER_PC_'.$userData['User']['id'];
887
888            //check
889            if (!$redis->get($key)) {
890                $redis->set(array(
891                    'key' => $key,
892                    'value' => 1,
893                    'expire' => 600 //10 minutes adjust to lessons
894                ));
895
896                //load model
897                $this->loadModel('UserMonitoring');
898
899                //update users monitoring
900                $this->UserMonitoring->upsert(array(
901                    'user_id' => $userData['User']['id'],
902                    'device_type' => 1 //pc
903                ));
904            }
905
906            // check user status
907            if (isset($userData['User']) && $userData['User']['status']=='9') {
908                $this->log('[NJ-65075] AppController.php L#'.__LINE__.' -- '.json_encode(array('user_data' => $userData['User'], 'request_data' => $this->request)), 'error');
909                $this->Auth->logout();
910                return $this->redirect(myTools::getUrl());
911            }
912        }
913
914        // load model
915        $this->loadModel('IpBlock');
916        $route = $this->params->url;
917
918        if ($this->IpBlock->blocked() || $this->isWithdrawn) {
919            $urlRedirect = myTools::getUrl();
920            $actionName = isset($this->request->params['action']) ? trim($this->request->params['action']) : null;
921
922            // pc if login
923            if ($this->Auth->loggedIn()) {
924                if (
925                    strtolower($actionName) != 'getalltextbookoption' && // reservation
926                    strtolower($actionName) != 'ajaxchapter' && // reservation
927                    !$this->request->is('ajax') &&
928                    !(strpos($route, 'cs/8') !== false) &&
929                    !(strpos($route, 'cs/confirm') !== false) &&
930                    !(strpos($route, 'cs/complete') !== false) &&
931                    strtolower($currentPageController) != 'htmltextbook' &&
932                    strtolower($currentPageController) != 'faq' &&
933                    !(strpos($route, 'Payment/zeuspayGetChallenge') !== false) &&
934                    !(strpos($route, 'paypal/create-billing-agreement-token') !== false) &&
935                    !($currentPageController == 'account' && $this->request->params['action'] == 'index')
936                ) {
937
938                    $this->loadModel('LessonOnair');
939                    // if has ongoing lesson
940                    $ongoingLesson = $this->LessonOnair->find('count', array(
941                        'conditions' => array(
942                            'status' => 3,
943                            'user_id' => $this->Auth->user('id')
944                        ),
945                        'recursive' => -1
946                    ));
947
948                    if (!$ongoingLesson) {
949                        $this->Cookie->delete('stealth');
950                        $memcached = new myMemcached();
951                        $memcached->delete('user-timediff-' . $this->Auth->user('id')); //delete timezone in memcache
952                        unset($_SESSION['google_login_token']);
953                        $this->Cookie->delete('rememberMe');
954
955                        // set cookie variable to be deleted
956                        $this->Cookie->name = 'searchTeacherForm';
957                        $this->Cookie->domain = $_SERVER['SERVER_NAME'];
958                        $this->Cookie->delete('searchReserveData');
959
960                        if ($this->Session->check('promoteApp')) {
961                            $this->Session->delete('promoteApp');
962                        }
963
964                        // reset timezone check
965                        if (isset($_COOKIE['timezone_dialog_show'])) {
966                            setcookie('timezone_dialog_show', 'on', 1);
967                        }
968
969                        // NC-7459
970                        $this->Session->delete('complimentary_user_disable_links'); // delete
971
972                        $this->loadModel('UsersIpLog');
973                        $this->UsersIpLog->sendSlackNotifToBlockedLoggedInUser(array('userId' => $userData['User']['id']));
974
975                        if (
976                            strtolower($this->request->params['controller']) == 'cs' ||
977                            (strtolower($this->request->params['controller']) == 'localize' && strtolower($actionName) == 'index') ||
978                            (strtolower($this->request->params['controller']) == 'entirefaq' && strtolower($actionName) == 'index')
979                        ) { // faq and cs
980                            if(isset($userData['User']['studysapuri_id'])) {
981                                $urlRedirect .= '/faq/category';
982                            } else {
983                                $urlRedirect .= '/cs/8';
984                            }
985                            return $this->redirect($urlRedirect);
986                        }
987                        $this->log('[NJ-65075] AppController.php L#'.__LINE__.' -- '.json_encode(array('user_data' => $userData['User'], 'request_data' => $this->request)), 'error');
988                        $this->Auth->logout();
989                        return $this->redirect($urlRedirect);
990                    }
991                }
992            // pc non login
993            } elseif ( 
994                !$this->request->is('ajax') &&
995                !empty($route) &&
996                !in_array($route, array('login')) &&
997                !(strpos($route, 'cs/8') !== false) &&
998                !(strpos($route, 'cs/confirm') !== false) &&
999                !(strpos($route, 'mobapp/close') !== false) &&
1000                !(strpos($route, 'cs/complete') !== false) &&
1001                !(strpos($route, 'mobapp/register') !== false) &&
1002                !(strpos($route, 'mobapp/home') !== false) &&
1003                !(strpos($route, 'paypal/create-billing-agreement-token') !== false) &&
1004                !isset($this->request->query['appVersion']) &&
1005                !isset($this->request->query['deviceType']) &&
1006                !isset($this->request->query['token']) &&
1007                strtolower($currentPageController) != 'htmltextbook' &&
1008                strtolower($currentPageController) != 'mobapp' &&
1009                !in_array($route, Configure::read('main_supported_language')) &&
1010                !(strpos($route, 'Payment/zeuspayGetChallenge') !== false)
1011            ) {
1012                if (
1013                        strtolower($this->request->params['controller']) == 'cs' || 
1014                        strtolower($this->request->params['controller']) == 'localize'
1015                    ) { // faq and cs
1016                    $urlRedirect .= '/cs/8'; 
1017                }
1018                return $this->redirect($urlRedirect);
1019            // web view
1020            } elseif (
1021                !$this->request->is('ajax') &&
1022                strtolower($currentPageController) != 'htmltextbook' &&
1023                strtolower($currentPageController) != 'class' &&
1024                (strtolower($currentPageController) == 'mobapp' || ($currentPageController == 'payment' && $actionName == 'mobapp_credit_charge_form')) &&
1025                !(strpos($route, 'mobapp/home') !== false) &&
1026                !(strpos($route, 'mobapp/close') !== false) &&
1027                !in_array($route, array('login')) &&
1028                !(strpos($route, 'paypal/create-billing-agreement-token') !== false) &&
1029                !empty($route) &&
1030                !in_array($route, Configure::read('main_supported_language'))
1031
1032            ) {
1033                if (
1034                    isset($this->request->query['token']) &&
1035                    !(strpos($route, 'mobapp/register') !== false)
1036                ) {
1037                    if ((
1038                            strpos($route, 'mobapp/cs') !== false ||
1039                            strpos($route, 'mobapp/confirm') !== false
1040                        ) &&
1041                        isset($this->request->query['c']) &&
1042                        $this->request->query['c'] == 8
1043                    ) {
1044                        // do nothing
1045                    } else if((
1046                                strpos($route, 'mobapp/cs') !== false ||
1047                                strpos($route, 'mobapp/confirm') !== false ||
1048                                strpos($route, 'mobapp/menu_inquiry') !== false ||
1049                                strpos($route, 'mobapp/faq') !== false
1050                            ) &&
1051                            (empty($this->request->query['c']) || (isset($this->request->query['c']) && $this->request->query['c'] != 8))
1052                    ) {
1053                        $urlRedirect = myTools::getUrl() . '/mobapp/cs' . myTools::getMobappToken($_GET) . '&c=8';
1054                        return $this->redirect($urlRedirect);
1055                    } else {
1056                        $appVersion = isset($this->request->query['appVersion']) && !empty($this->request->query['appVersion']) ? $this->request->query['appVersion'] : 0;
1057                        $deviceType = isset($this->request->query['deviceType']) && !empty($this->request->query['deviceType']) ? $this->request->query['deviceType'] : 0;
1058                        if(!empty($appVersion) && !empty($deviceType)) {
1059                            if (in_array($deviceType, [1,2,3])) {
1060                                $appVersionCompare = version_compare($appVersion, Configure::read('ip_block_app_version')[$deviceType], '<');
1061                                if (!$appVersionCompare) {
1062                                    return $this->redirect('nativecamp://view/is_blocked');
1063                                }
1064                            }
1065                        }
1066                    }
1067                    
1068                } else {
1069                    $urlRedirect = myTools::getUrl() . '/mobapp/home' . myTools::getMobappToken($_GET);
1070                    if (
1071                        strpos($route, 'mobapp/home') !== false ||
1072                        (
1073                            (
1074                                strpos($route, 'mobapp/cs') !== false ||
1075                                strpos($route, 'mobapp/confirm') !== false
1076                            ) &&
1077                            isset($this->request->query['c']) &&
1078                            $this->request->query['c'] == 8
1079                        )
1080                    ) {
1081                        // do nothing
1082                    } else {
1083                        // for mobapp cs blocked ip address
1084                        $route = parse_url($route, PHP_URL_PATH);
1085                        if (
1086                                strpos($route, 'mobapp/cs') !== false || 
1087                                strpos($route, 'mobapp/faq') !== false 
1088                            ) {
1089                            $urlRedirect = myTools::getUrl() . '/mobapp/cs' . myTools::getMobappToken($_GET) . '&c=8';
1090                        }
1091
1092                        return $this->redirect($urlRedirect);
1093                    }
1094                }
1095            }
1096        }
1097
1098        // 4372 textbook name cached
1099        $textbookNamesCached = $memcached->get(Configure::read('textbook_names_cache_key'));
1100
1101        // set shared userData
1102        $this->sharedUserData = $userData;
1103
1104        // set userCurrencyCode
1105
1106        $defaultCurrencyCode = Configure::read('default.user_currency');
1107        $allowedCurrencies = Configure::read('pc_allowed_currencies');
1108        $currencyCode = isset($allowedCurrencies[$this->localizeDir]) ? $allowedCurrencies[$this->localizeDir] : $defaultCurrencyCode;
1109
1110        if(isset($this->mobAppUserData) && $this->mobAppUserData['User']['currency_code']) {
1111            $setCurrencyCode = $this->mobAppUserData['User']['currency_code'];
1112        } else {
1113            $setCurrencyCode = isset($this->sharedUserData) && is_array($this->sharedUserData) && $this->sharedUserData['User']['currency_code'] ? $this->sharedUserData['User']['currency_code'] : $currencyCode;
1114        }
1115        $this->set('userSetCurrencyCode', $setCurrencyCode);
1116        
1117        myTools::setCurrencyCode($setCurrencyCode);
1118        
1119        // remove success session from registration
1120        $this->Session->delete('registerSuccessEnd');
1121        $this->set('textbookNamesCached', $textbookNamesCached);
1122        $this->set('auth', $this->Auth);
1123        $this->set(compact('userData'));
1124        $this->set('isMobileRequestHandler', $this->RequestHandler->isMobile());
1125        //timezone data
1126        $this->set(array(
1127            'timeDiff' => $this->timeDiff,
1128            'timeDiffSecond' => $this->timeDiffSecond,
1129            'displayTime' => $this->displayTime,
1130            'utcOffset' => $this->utcOffset,
1131            'allowedCoupon' => $this->allowedCoupon ? true : false
1132        ));
1133        
1134        // NC-7459 check complimentary user's status, force redirect to conversion page if expired.
1135        // @TODOs check mobapp and payment, lessons, sp pages.
1136        // callLessonAlertandStartButton
1137        // ($currentPageController != 'class' && $currentPageController != 'htmltextbook')
1138        $excludeControllers = array(
1139            "mobapp", 
1140            "payment", 
1141            "cs", 
1142            "lessonfinish", 
1143            "class", 
1144            "htmltextbook", 
1145            "register"
1146        );
1147        $excludeActions = array(
1148            "continuoususe_advertising", 
1149            "continuoususe_promotion", 
1150            "logout", 
1151            "callLessonAlertandStartButton", 
1152            "credit_form", 
1153            "credit_form_process", 
1154            "credit_form_success", 
1155            "complete", 
1156            "change_to_premium", 
1157            "premium", 
1158            "wp_credit_form", 
1159            "notice_to_user", 
1160            "spcreditform"
1161        );
1162
1163        $this->CompCodeUsage->openDBReplica();
1164        $getUserCompStatus = $this->CompCodeUsage->find('first', array(
1165                'fields' => [
1166                    'CompCodeUsage.code',
1167                    'CompCodeUsage.expire_flg',
1168                    'CompCodeUsage.used_at'
1169                ],
1170                'recursive' => -1,
1171                'conditions' => array('CompCodeUsage.user_id' => $this->Auth->user('id'),
1172                 'CompCodeUsage.active_flg' => 1)
1173            ));
1174        $this->CompCodeUsage->closeDBReplica();
1175
1176        $complimentaryCode = "";
1177        $chargeDate = "";
1178        $compCodeIsExpired = "";
1179        if(!empty($getUserCompStatus)){
1180            $complimentaryCode = $getUserCompStatus['CompCodeUsage']['code'];
1181            $chargeDate = $getUserCompStatus['CompCodeUsage']['used_at'];
1182            $compCodeIsExpired = $getUserCompStatus['CompCodeUsage']['expire_flg'];
1183        }
1184
1185        $userDataForCompStatus = array(
1186            'id' => $this->Auth->user('id'),
1187            'complimentary_code' => $complimentaryCode,
1188            'first_charge_date' => $chargeDate
1189        );
1190        
1191        $currentController = isset($this->request->params['controller']) ? trim(strtolower($this->request->params['controller'])) : null;
1192        $currentAction = isset($this->request->params['action']) ? trim($this->request->params['action']) : null;
1193        $conditions = $this->Auth->loggedIn()
1194        && isset($userData['User'])
1195        && isset($complimentaryCode)
1196        && isset($userData['User']['payment_plan_id'])
1197        && $userData['User']['payment_plan_id'] == Configure::read('payment_plans.complimentary_plan')
1198        && !$this->request->is('ajax')
1199        && !in_array($currentController, $excludeControllers)
1200        && !in_array($currentAction, $excludeActions);
1201
1202        $this->loadModel('ComplimentaryCode');
1203        $comPlanData = $this->ComplimentaryCode->getUserComplimentaryPlanStatus($userDataForCompStatus);
1204        // this code is for redirection to mypage if condition is not satisfied
1205        if (isset($comPlanData['complimentary_plan_conversion_url']) && 
1206            ($comPlanData['complimentary_plan_conversion_url'] === '/continuoususe/advertising' || 
1207            $comPlanData['complimentary_plan_conversion_url'] === '/continuoususe/promotion')) {
1208            $conditions = $conditions && $compCodeIsExpired;
1209        }
1210        
1211
1212        if ($conditions) {
1213            // check
1214            if (
1215                isset($comPlanData['compliemntary_plan_can_lesson'])
1216                && !$comPlanData['compliemntary_plan_can_lesson']
1217                && isset($comPlanData['complimentary_plan_conversion_url'])
1218            ) {
1219                // $comPlanData['complimentary_plan_conversion_url'] = "/continuoususe/promotion";
1220                $complimentaryConversionType = isset($comPlanData['template_type']) ? $comPlanData['template_type'] : 0;
1221                $coin_award = isset($comPlanData['coin_award']) ? $comPlanData['coin_award'] : 0;
1222                $this->Session->write('complimentary_user_disable_links', true);
1223                return $this->redirect(myTools::getUrl() . $comPlanData['complimentary_plan_conversion_url']);
1224            }
1225        }
1226
1227
1228        // parent avatar json data
1229        $avatarJson = null;
1230        $avS3PageCont = array('mypage','waiting','favorite');
1231        $avS3PageActions = array('index');
1232        if ( 
1233            $this->Auth->loggedIn() && 
1234            in_array($currentController, $avS3PageCont) && 
1235            in_array($currentAction, $avS3PageActions)
1236        ) {
1237            $avatarJson = TeacherTable::getAvatarChildJson();
1238        }
1239
1240        // NJ-51
1241        $lessonPriorityControllerArr = Configure::read('priority_lesson_group_data_info.web.controller');
1242        $lessonPriorityActionArr = Configure::read('priority_lesson_group_data_info.web.action');
1243        if ( 
1244            $this->Auth->loggedIn() && 
1245            in_array($currentController, $lessonPriorityControllerArr) && 
1246            in_array($currentAction, $lessonPriorityActionArr)
1247        ) {
1248            $this->studentLessonPriorityTimeDelayInSeconds = $this->User->userPriorityDelay( array( 'user_id' => $this->Auth->user('id') ) );
1249        }
1250
1251        // delete diablelink flag, if navigate to not restricted page.
1252        if (
1253            !in_array($currentAction, $excludeActions)
1254            && !$this->request->is('ajax')
1255        ) {
1256            $this->Session->delete('complimentary_user_disable_links'); // delete
1257        }
1258
1259        // check if there is/are unsave user lesson connection   data.
1260        if (!$this->request->is('ajax')) {
1261            $cookieKey = 'user_lesson_connection_speed_unsave_data';
1262
1263            // - delete cookie if exists
1264            if (isset($_COOKIE[$cookieKey])) {
1265                if ($this->LessonConnectionSpeedDetail->updateConnectionSpeedInfo($cookieKey, 'user')) {
1266                    unset($_COOKIE[$cookieKey]);
1267                    setcookie($cookieKey, null, -1, '/');
1268                }
1269            }
1270        }
1271
1272        $this->isStudySapuriUser = ($this->isStudySapuriTosUser || $this->studySapuriId);
1273        $this->allowedCurrencies = Configure::read('pc_allowed_currencies');
1274        // NC-7922 : Stasapu cs admin domains not allow access
1275        $this->checkStasapuDomain();
1276        // - set current controller and action
1277        $this->set('avatarJson', $avatarJson);
1278        $this->set('current_controller', $currentController);
1279        $this->set('current_action', $currentAction);
1280        $this->set('studySapuriId', $this->studySapuriId);
1281        $this->set('isStudySapuriTosUser', $this->isStudySapuriTosUser);
1282        $this->set('isStudySapuriUser', $this->isStudySapuriUser);
1283        $this->set('studentLessonPriorityTimeDelayInSeconds', $this->studentLessonPriorityTimeDelayInSeconds);
1284        $this->set('isTemporaryPassword', $this->isTemporaryPassword);
1285        $this->set('defaultCameraSetting', $this->defaultCameraSetting);
1286        $this->set('userCDNPath', Configure::read('user.cdn_path_webroot'));
1287                
1288        //NJ-3882
1289        if (isset($userObj) && $userObj) {
1290            $membershipType = $userObj->getMembershipTypeIndex();
1291            $this->userMembershipType = $membershipType;
1292            $this->set('membershipType', $membershipType);
1293        }
1294
1295        //NJ-13670 New Year Part 1 campaign
1296        $newYear1DesignCampaign = false;
1297        $newYear1CampDateArr = Configure::read('campaign_config.new_year_part_1.period');
1298        if (
1299            (
1300                isset($userObj) && $userObj 
1301                && in_array($userObj->getMembershipTypeIndex(), Configure::read('campaign_config.new_year_part_1.design_valid_memberships'))
1302                && time() >= strtotime($newYear1CampDateArr['start']) && time() <= strtotime($newYear1CampDateArr['end'])
1303            )
1304            || (
1305                (!isset($userObj) || !$userObj)
1306                && time() >= strtotime($newYear1CampDateArr['start']) && time() <= strtotime($newYear1CampDateArr['end'])
1307            )
1308        ) {
1309            $newYear1DesignCampaign = true;
1310        }
1311        $this->set('newYear1DesignCampaign', $newYear1DesignCampaign);
1312
1313        //NJ-14237 Amazon Gift campaign
1314        $amazonGiftCampaign = false;
1315        $amazonGiftCampDateArr = Configure::read('campaign_config.amazongift.period');
1316        if (
1317            (
1318                isset($userObj) && $userObj 
1319                && !$this->isStudySapuriUser
1320                && in_array($userObj->getMembershipTypeIndex(), Configure::read('campaign_config.amazongift.valid_memberships'))
1321                && time() >= strtotime($amazonGiftCampDateArr['start']) && time() <= strtotime($amazonGiftCampDateArr['end'])
1322                && $userObj->currency_code == Configure::read('default.user_currency')
1323                && $this->localizeDir == Configure::read('default.user_language')
1324                && !$this->isStudySapuriUser
1325                && $this->action != 'createAccountStudysapuri'
1326            )
1327            || (
1328                (!isset($userObj) || !$userObj)
1329                && time() >= strtotime($amazonGiftCampDateArr['start']) && time() <= strtotime($amazonGiftCampDateArr['end'])
1330                && $this->localizeDir == Configure::read('default.user_language')
1331                && !$this->isStudySapuriUser
1332                && $this->action != 'createAccountStudysapuri'
1333            )
1334        ) {
1335            if($route == '' || strtolower($route) == 'register'){
1336                $amazonGiftCampaign = true;
1337            }
1338        }
1339        $this->set('amazonGiftCampaign', $amazonGiftCampaign);
1340
1341        $googleTagManager = Configure::read('google_tag_manager.default');
1342        if ($firstSegment) {
1343            $globalLanguageAllowed = Configure::read('global_language.allowed_list');
1344
1345            if (in_array($this->localizeDir, $globalLanguageAllowed)) {
1346                $googleTagManager = Configure::read('google_tag_manager.oversies');
1347            } else if (strpos($firstSegment, 'tutors') !== false || strpos($firstSegment, 'recruit') !== false) {
1348                $googleTagManager = Configure::read('google_tag_manager.others');
1349            }
1350        }
1351        $this->set('googleTagManager', $googleTagManager);
1352
1353        if(
1354            (isset($this->request->query['deviceType']) && $this->request->query['deviceType']) &&
1355            (isset($this->request->query['appVersion']) && $this->request->query['appVersion'])) {
1356            $this->NCPlusPositionUrlScheme($this->request->query['appVersion'], $this->request->query['deviceType']);
1357        }
1358        // NJ-37156: Set flag for lite plan users in all pages
1359        $isLitePlanUser = is_array($userData) && in_array($userData['User']['payment_plan_id'], Configure::read('lite_payment_plans')) ? 1 : 0;
1360        $this->set('isLitePlanUser', $isLitePlanUser);
1361
1362        // Study Abroad
1363        $ryugakuAllowedLang = Configure::read('ryugaku_language.allowed_list');
1364        if (in_array($currentController, array('studyabroad', 'studyabroadcreateestimate'))  && !in_array($this->localizeDir, $ryugakuAllowedLang)) {
1365            return $this->redirect('/');
1366        }
1367
1368        //- NJ-27262
1369        //- Redirect chocotto user to download page if logs on PC/SP
1370        if($this->Auth->loggedIn()) {
1371
1372            if (isset($userObj) && $userObj && isset($userObj->payment_plan_id)) {
1373                $isChocottoUser = in_array($userObj->payment_plan_id, [
1374                    Configure::read('payment_plans.free_trial_chocotto'), 
1375                    Configure::read('payment_plans.chocotto_plan')
1376                ]);
1377                
1378                // - check if not accessing study abroad
1379                $notStudyAbroadAccess = (
1380                    (strpos($route, 'study_abroad') === false) 
1381                    && !$this->request->is('ajax') 
1382                    && !in_array($currentController, array('studyabroad', 'studyabroadcreateestimate', 'studyabroadfavorite'))
1383                );
1384
1385                if($isChocottoUser && $notStudyAbroadAccess) {
1386                    $this->log('[NJ-65075] AppController.php L#'.__LINE__.' -- '.json_encode(array('user_data' => $userObj, 'request_data' => $this->request, 'param_data' => $this->params)), 'error');
1387                    $this->Auth->logout();
1388                    $this->redirect('/chocotto_camp_success');
1389                }
1390            }
1391        }
1392        
1393        // Initialize $userCorpId either $appUserData or $userData
1394        $userCorpId = null;
1395        if (isset($appUserData['User']['corporate_id']) && !empty($appUserData['User']['corporate_id'])) {
1396            $userCorpId = $appUserData['User']['corporate_id'];
1397        } elseif (isset($userData['User']['corporate_id']) && !empty($userData['User']['corporate_id'])) {
1398            $userCorpId = $userData['User']['corporate_id'];
1399        }
1400
1401        // Check if the user is corporate, retrieve the payment method if corporate_id exists
1402        if (isset($userCorpId) && !empty($userCorpId)) {
1403            $corpIndPayment = $this->Corporate->getPaymentMethod($userCorpId);
1404            if ($corpIndPayment == 1) {
1405                $this->isIndividualCorp = true;
1406            }
1407        }
1408
1409        // Set the variable to check if the user is an individual corporate
1410        $this->set('isIndividualCorp', $this->isIndividualCorp);
1411
1412        // check if Stripe is Supported
1413        $this->checkStripeSupported($userData);
1414        
1415        $custom_lang_format_flag= false;
1416        if(isset($this->localizeDir) && in_array($this->localizeDir, Configure::read("custom_lang_format_support"))) { 
1417            $custom_lang_format_flag = true;
1418        }
1419        $this->set("custom_lang_format_flag",$custom_lang_format_flag);
1420
1421        $currentLang_iso = $this->Session->read('Config.language_iso_1');
1422        
1423        // NJ-57390 - redirect to register or download app 
1424        if (!$this->request->is('post') && !$this->request->is('ajax') && !isset($this->request->query['appVersion'])) {
1425            if(!in_array($this->name, ['Home', 'Register', 'Login', 'Mobapp', 'MobappInquiry','SpTextbook', 'HtmlTextbook', 'Account']) && in_array($currentLang_iso, ['fr', 'de', 'zh-cn'])) {
1426                $url = myTools::getUrl();
1427
1428                if($this->Auth->loggedIn()) {
1429                    $this->log('[NJ-65075] AppController.php L#'.__LINE__.' -- '.json_encode(array('user_data' => $userData, 'lang_iso' => $currentLang_iso, 'request_data' => $this->request)), 'error');
1430                    $this->Auth->logout();
1431                    return $this->redirect($url . '/' . $currentLang_iso . '?download_app=true');
1432                } else {
1433                    return $this->redirect($url . '/' . $currentLang_iso . '/register');
1434                }
1435            }
1436        }
1437    }
1438    
1439    public function setLocalization() {
1440        $source = $this->Cookie->read('source');
1441        if (empty($source)) {
1442            $source = isset($_GET['source']) ? $_GET['source'] : '';
1443        }
1444
1445        // check if demohtmltextbook view and has lang params
1446        if(
1447            isset($this->request->params['controller']) && 
1448            strtolower($this->request->params['controller']) == 'demohtmltextbook'
1449        ){
1450            if(isset($this->request->query['lang']) && $this->request->query['lang']){
1451                $this->localizeDir = $this->request->query['lang'];
1452            }else{
1453                $this->localizeDir = Configure::read('default.user_language');
1454            }
1455
1456        // - if has localize directory - main override!!
1457        } else if (isset($this->request->data['localizeDir']) && mb_strlen($this->request->data['localizeDir'])) {
1458            $this->localizeDir = $this->request->data['localizeDir'];
1459
1460        // - if AJAX and cookie contains value
1461        } else if (
1462            $this->request->is('ajax') 
1463            && $this->Cookie->check('localizeDir')
1464            && (mb_check_encoding($this->Cookie->read('localizeDir'), 'UTF-8')  && strpos($this->Cookie->read('localizeDir'), '�') == false)
1465        ) {
1466            $this->localizeDir = $this->Cookie->read('localizeDir');
1467            
1468            
1469        // - else
1470        } else {
1471            // - if has language parameter
1472            if (
1473                ($this->request && isset($this->request->language) && $this->request->language != Configure::read('default.user_language')) || 
1474                ($this->localizeDir != Configure::read('default.user_language'))
1475            ) {
1476                $this->localizeDir = $this->request->language;
1477
1478            // - whitelisted actions
1479            } else if (
1480                // - if has valid action
1481                isset($this->request->params['action']) && $this->Cookie->check('localizeDir') 
1482
1483                // - valid format
1484                && (mb_check_encoding($this->Cookie->read('localizeDir'), 'UTF-8') && strpos($this->Cookie->read('localizeDir'), '�') == false)
1485                
1486                // - if not home
1487                && !($this->request->params['action'] == "index" && $this->request->params['controller'] == "home")
1488                && !($this->request->params['action'] == "price_mobapp" && $this->request->params['controller'] == "Usage")
1489                && !($this->request->params['action'] == "features" && $this->request->params['controller'] == "mobapp")
1490                && !($this->request->params['action'] == "service_mobapp" && $this->request->params['controller'] == "Usage")
1491                && !($this->request->params['action'] == "menu_inquiry" && $this->request->params['controller'] == "Mobapp")
1492                && !($this->request->params['action'] == "favorite_teachers" && $this->request->params['controller'] == "Mobapp")
1493                && $source != 'okpanda'
1494            ) {
1495                $this->localizeDir = $this->Cookie->read('localizeDir');
1496
1497            // - if has language "la" in query
1498            } else if (
1499                isset($this->request->query['la']) && $this->request->query['la'] != Configure::read('default.user_language')
1500                
1501                // - if home
1502                && (
1503                    ($this->request->params['action'] == "index" && $this->request->params['controller'] == "home") ||
1504                    (isset($this->request->params['overrideLocalizeDir']) && $this->request->params['overrideLocalizeDir']) ||
1505                    ($this->request->params['action'] == "price_mobapp" && $this->request->params['controller'] == "Usage") ||
1506                    ($this->request->params['action'] == "features" && $this->request->params['controller'] == "mobapp") ||
1507                    ($this->request->params['action'] == "service_mobapp" && $this->request->params['controller'] == "Usage") ||
1508                    ($this->request->params['action'] == "menu_inquiry" && $this->request->params['controller'] == "Mobapp") ||
1509                    $source == 'okpanda' ||
1510                    (isset($this->request->params['overrideLocalizeDir']) && $this->request->params['overrideLocalizeDir'])
1511                )
1512            ) {
1513                $this->localizeDir = $this->request->query['la'];
1514            }
1515        }
1516
1517        // get allowed languages
1518        $allowedLanguages = array_flip(Configure::read('pc_allowed_currencies'));
1519
1520        // get currency code
1521        $this->loadModel('GeoIPCountryCurrency');
1522        $currencyCode = $this->GeoIPCountryCurrency->getCurrencyCode();
1523        $this->localizeIPLang = $currencyCode;
1524
1525        $eurAllowedLanguageCodes = array_keys(Configure::read('pc_allowed_currencies'), 'EUR'); // ['fr', 'de'] for now at NJ-57390
1526        $countryCode = $this->GeoIPCountryCurrency->getCountryCode();
1527
1528        if (!empty($this->params->params['language']) && $this->params->params['language'] == 'zh-cn') {
1529            $ipLanguage = $this->params->params['language'];
1530        } else if(in_array(strtolower($countryCode), $eurAllowedLanguageCodes)) {
1531            $ipLanguage = strtolower($countryCode);
1532        } else {
1533            $ipLanguage = !empty($currencyCode) && $currencyCode != 'USD' && isset($allowedLanguages[$currencyCode]) ? $allowedLanguages[$currencyCode] : Configure::read('default.user_language');
1534        }
1535
1536        $controller = $this->params->params['controller'];
1537        $action = $this->params->params['action'];
1538        $route = $this->params->url;
1539        $ipRestrictionFlg = true;
1540
1541        // if vietnam language
1542        if ($ipLanguage == 'vi') {
1543            // check if vnStealth is set
1544            if (isset($this->request->query['vnStealth'])) {
1545                if ($this->request->query['vnStealth'] == 'off') {
1546                    $this->Cookie->delete('excludeIpRestriction');
1547                } elseif ($this->request->query['vnStealth'] == 'on') {
1548                    $this->Cookie->write('excludeIpRestriction', true);
1549                }
1550            }
1551        } else {
1552            $this->Cookie->delete('excludeIpRestriction');
1553        }
1554
1555        if ($this->Cookie->read('excludeIpRestriction')) {
1556            $ipRestrictionFlg = false;
1557        }
1558
1559        // restriction for france and germany, this will not redirect to /de or /fr if ip is germany or france
1560        if (in_array($ipLanguage, ['fr', 'de'])) {
1561            $ipRestrictionFlg = false;
1562        }
1563
1564        // change language based on ip lang if
1565        // if ip language is ko or zh-tw and request language is not equals to ip language
1566        if (
1567            !$this->request->is('post') &&
1568            !$this->request->is('ajax') &&
1569            !isset($this->request->query['la']) &&
1570            in_array($ipLanguage, Configure::read('global_language.allowed_list')) &&
1571            !in_array($action, array('sendDLlink', 'zeuspay', 'corporateZeuspay', 'getWPPaymentResult', 'getAfteePaymentResult', 'stripepay', 'stripepay_manual')) &&
1572            $controller != 'Api' &&
1573            strtolower($controller) != 'mobapp' &&
1574            !(strpos($route, 'mobapp/') !== false) &&
1575            !(strpos($route, 'HtmlTextbook/') !== false) && // for pc textbook
1576            !(strpos($route, 'sp/textbook/') !== false) && // for app textbook
1577            !(strpos($route, 'textbook/getSpeech/') !== false) && // for audio
1578            $ipRestrictionFlg
1579            || // if url was sent from sns sharing
1580            (
1581                isset($_GET["nc_share_ref"]) &&
1582                $_GET["nc_share_ref"] == "nc_sns_share" &&
1583                !(
1584                    (strpos($_SERVER["HTTP_USER_AGENT"], 'facebookexternalhit') !== false) ||
1585                    (strpos($_SERVER["HTTP_USER_AGENT"], 'Twitterbot') !== false) ||
1586                    (strpos($_SERVER["HTTP_USER_AGENT"], 'line-poker') !== false)
1587                )
1588            )
1589            && $source != 'okpanda'
1590        ) {
1591            $isPaymentUrl =  (strpos($route, 'payment/mobapp_') !== false);
1592            if (!empty($this->request->language) && $this->request->language != $ipLanguage && !$isPaymentUrl) {
1593                return $this->redirectUsingIpLang($ipLanguage);
1594            } else {
1595                if (
1596                    $this->checkControllerActionExist($controller, $action) &&
1597                    $this->request->language != $ipLanguage &&
1598                    !$isPaymentUrl
1599                ) {
1600                    return $this->redirectUsingIpLang($ipLanguage);
1601                }
1602            }
1603        }
1604
1605        //NJ-32821
1606        $referringURL = @$_SERVER['HTTP_REFERER'];
1607        // Check if came from zh-tw blog
1608        if (!empty($referringURL)) {
1609            $pattern = '/\/([^\/]+)\/blog\//';
1610            if (preg_match($pattern, $referringURL, $matches) && count($matches) > 1) {
1611                   $zh_tw = $matches[1];
1612                   if(!empty($zh_tw) && $zh_tw == "zh-tw") {
1613                       $this->localizeDir = $zh_tw;
1614                   }
1615            } 
1616        } 
1617        
1618        // - set cookie information
1619        $this->Cookie->write('localizeDir', $this->localizeDir);
1620        Configure::write('default.localization', $this->localizeDir);
1621        $this->set('localizeDir', $this->localizeDir);
1622
1623        // - if has default language
1624        if ( $this->localizeDir != Configure::read('default.user_language') ) {
1625            if (
1626                // - if not supported
1627                (
1628                    !in_array($this->localizeDir, Configure::read('global_language.allowed_list')) 
1629                    && $this->request->params['controller'] != 'home'
1630                )
1631
1632                // - and not static page
1633                && (
1634                    $this->request->params['controller'] != 'static' 
1635                    && $this->request->params['action'] != 'privacy' 
1636                    && $this->request->params['action'] != 'privacy'
1637                )
1638
1639                // - and not api controller
1640                && (
1641                    $this->request->params['controller'] != 'Api' 
1642                    && $this->request->params['action'] != 'sendDLlink'
1643                )
1644
1645                // - if not mobapp link
1646                && (
1647                    strtolower($this->request->params['controller']) != 'mobapp' 
1648                )
1649
1650                // - if not mobapp link
1651                && (
1652                    strtolower($this->request->params['controller']) != 'payment' 
1653                    && $this->request->params['action'] != 'getHostedPage'
1654                )
1655
1656                // - if not cs page
1657                && (
1658                    strtolower($this->request->params['controller']) != 'cs' 
1659                )
1660
1661                // - if not reregister
1662                && (
1663                    strtolower($this->request->params['controller']) != 'reregister' 
1664                )
1665                
1666                // - if not textbook
1667                && (
1668                    strtolower($this->request->params['controller']) != 'htmltextbook' 
1669                )
1670
1671                
1672                // NJ-11650 - if not FAQ
1673                && (
1674                    strtolower($this->request->params['controller']) != 'entirefaq' 
1675                )
1676                // - if not textbook
1677                && (
1678                    strtolower($this->request->params['controller']) != 'demohtmltextbook' 
1679                )
1680
1681                // - if login + register from Okpanda
1682                && $source != 'okpanda'
1683
1684            ) {
1685                if ($this->Auth->loggedIn()) {
1686                    $this->log('[NJ-65075] AppController.php L#'.__LINE__.' -- '.json_encode(array('localizeDir' => $this->localizeDir, 'request_data' => $this->request)), 'error');
1687                    return $this->redirect($this->Auth->logout());
1688                }
1689                return $this->redirect('/');
1690            }
1691
1692            $this->baseUrl =  myTools::getUrl() . '/' . Configure::read('default.localization');
1693            $this->set('noIndexFlg', true);
1694            
1695            $lang_iso_1 = $this->localizeDir;
1696            $lang_iso_1 = $lang_iso_1 == 'cz' ? 'cs' : $lang_iso_1;
1697            $language_code = $this->CountryCode->convertLangIso(array(
1698                'language_code' => $lang_iso_1,
1699                'target_iso' => 2
1700            ));
1701            $this->Session->write('Config.language', $language_code);
1702            $this->Session->write('Config.language_iso_1', $lang_iso_1);
1703            $this->set('html_lang_iso_1', $lang_iso_1);
1704        } else {
1705
1706            $this->baseUrl =  myTools::getUrl();
1707            $this->set('html_lang_iso_1', $this->localizeDir);    
1708        }
1709
1710        // - apply translation for error message
1711        $this->Auth->authError = __d("login", "再度ログインしなおしてください。");
1712        $this->Auth->loginError = __d("login", "メールアドレス、またはパスワードに誤りがあります。");
1713    }
1714
1715    /**
1716     * redirect with language based on ip address
1717     * @param string  $ipLanguage
1718     * @return string new rurl
1719     */
1720    private function redirectUsingIpLang($ipLanguage) {
1721        $webUrl = $_SERVER['REQUEST_URI'];
1722        $segment = explode('/', $webUrl);
1723
1724        $isSNSShare = false;
1725        // if url has nc_share_ref or shared to SNS 
1726        // parse url to remove query for sns share "nc_share_ref"
1727        if(isset($_GET["nc_share_ref"]) && $_GET["nc_share_ref"]== "nc_sns_share" ){
1728            $parsedUrl = parse_url($webUrl);
1729            parse_str( $parsedUrl['query'], $parameters ); 
1730            unset( $parameters['nc_share_ref'] ); 
1731            $newQuery = http_build_query($parameters);
1732            $isSNSShare = true;
1733        }
1734        
1735
1736        if (!isset($this->request->language)) {
1737            $segment[0] = '/' . $ipLanguage;
1738            $newUrl = implode('/', $segment);
1739            // apply new url if SNS share
1740            if($isSNSShare){
1741                $newUrl = '/' . $ipLanguage . $parsedUrl['path'] .'?'. $newQuery;
1742            }
1743        } else {
1744            $segment[1] = str_replace($segment[1], $ipLanguage, $segment[1]);
1745            $newUrl = implode('/', $segment);
1746            // apply new url if SNS share
1747            if($isSNSShare){
1748                $newParsedUrl = rtrim(str_replace('/'.$this->request->language, '', $parsedUrl['path']), '/');
1749                $newUrl = '/' .  str_replace($segment[1], $ipLanguage, $segment[1]) . $newParsedUrl .'?'. $newQuery;
1750            }
1751        }
1752
1753        return parent::redirect(myTools::getUrl() . $newUrl, null, false);
1754    }
1755
1756    public function redirect($url, $status = null, $exit = true) {
1757        //override redirect to login page with status 301
1758        if (($url == '/login' || $url == myTools::getUrl() . '/user/login') && strtolower($this->request->params['controller']) != 'login') {
1759            $this->response->disableCache();
1760            $url = myTools::getUrl() . '/user/login';
1761            $status = 301;
1762        }
1763
1764        // - if contains mobapp, do not do any processing
1765        if (is_string($url) && strpos($url, "/mobapp") !== false) {
1766            return parent::redirect($url, $status, $exit);
1767        }
1768        
1769        # redirect to Localized URL
1770        if (
1771            $this->localizeDir != 'ja' &&
1772            ((!is_array($url) && $this->localizeDir && strpos($url, "/" . $this->localizeDir) === false) ||
1773            (is_array($url) && $this->localizeDir && !isset($url['language'])))
1774        ) {
1775
1776            if (is_array($url)) {
1777                $url['language'] = $this->localizeDir;
1778            } else {
1779                $parseDomain = false;
1780                #if not nativecamp site avoid editing url
1781                if (strpos($url, 'http://') === 0 || strpos($url, 'https://') === 0) {                    
1782                    $parseUrl = parse_url($url);
1783
1784                    if ($parseUrl['host'] != $_SERVER['HTTP_HOST']) {
1785                        return parent::redirect($url, $status, $exit);
1786                    } else {
1787                        $parseDomain = true;
1788                    }
1789                }
1790                #if not nativecamp not https
1791                if (strpos($url, 'http:') !== false && $parseDomain) {
1792                    $url = str_replace('http:', 'https:', $url);
1793                }
1794                
1795                $baseUrl = myTools::getUrl();
1796                $userDir = "/user";
1797                if (strpos($url, $baseUrl) !== false && strpos($url, $userDir) !== false) {
1798                    $replace = $baseUrl . $userDir;
1799                    $replaceWith = $baseUrl . "/" . $this->localizeDir;
1800                    $url = str_replace($replace, $replaceWith, $url);
1801                } elseif (strpos($url, $baseUrl) !== false) {
1802                    $replace = $baseUrl;
1803                    $replaceWith = $baseUrl . "/" . $this->localizeDir;
1804                    $url = str_replace($replace, $replaceWith, $url);
1805                } else {
1806                    $url = $baseUrl . '/' . $this->localizeDir . $url;
1807                }
1808            }
1809        }
1810
1811        if ($this->localizeDir == 'ja') {
1812            if (is_array($url)) {
1813                unset($url['language']);
1814            } else {
1815                $checkBaseUrl = myTools::getUrl() . '/ja';
1816                $this->log("Redirect : " . __METHOD__ . " (line " . __LINE__ . ") checkBaseUrl = " . $checkBaseUrl . ' ' . $url, "error");
1817                // if url contains ja, replace it with base url
1818                if (strpos($url, $checkBaseUrl) !== false) {
1819                    $replaceWith = myTools::getUrl();
1820                    $url = str_replace($checkBaseUrl, $replaceWith, $url);
1821                } elseif (strpos($url, '/ja/') === 0) {
1822                    $url = str_replace('/ja', '', $url);
1823                }
1824            }
1825        } 
1826
1827        return parent::redirect($url, $status, false);
1828    }
1829
1830    /**
1831    * set Config.language using parameter or browser language
1832    */
1833    public function setConfigLanguage() {
1834        $lang_iso_1 = $language_code = NULL;
1835        $baseUrl = myTools::getUrl();
1836        $localizeNonLpPages = array('tos', 'privacy'); // non LP pages
1837
1838        if ($this->Auth->loggedIn()) {
1839            # get user data
1840            $user = $this->sharedUserData;
1841            $lang_iso_1 = $user['User']['native_language2'] ? $user['User']['native_language2'] : '';
1842        } else {
1843
1844            $path = $this->parseUrl['path'];
1845            $globalLang = Configure::read('global_language.list');
1846
1847            if ($path != '/') {
1848                $segment = explode('/', $path);
1849                $firstSegment = isset($segment[1])? $segment[1]:'';
1850
1851                // redirect to main url
1852                if ($firstSegment == 'ja') {
1853                    $this->log("Redirect : " . __METHOD__ . " (line " . __LINE__ . ") firstSegment = ja, " . $baseUrl , "debug");
1854                    return $this->redirect($baseUrl);
1855                }
1856
1857                // set lang iso_639_1
1858                $lang_iso_1 = $firstSegment == 'cz' ? 'cs' : (strpos($globalLang, $firstSegment) !== false ? $firstSegment : Configure::read('original.default.iso_639_1'));
1859            }
1860        }
1861
1862        if (!empty($lang_iso_1)) {
1863            //return iso_639_2 if supported language
1864            $language_code = $this->CountryCode->convertLangIso(array(
1865                'language_code' => $lang_iso_1,
1866                'target_iso' => 2
1867            ));
1868        } else {
1869            // set default
1870            $language_code = Configure::read('original.default.iso_639_2');
1871            $lang_iso_1 = Configure::read('original.default.iso_639_1');
1872        }
1873
1874        //set sessions
1875        $this->Session->write('Config.language', $language_code);
1876        $this->Session->write('Config.language_iso_1', $lang_iso_1);
1877        setcookie('lang', $lang_iso_1, 0, '/');
1878
1879        # set layoutLang_iso for url in view files
1880        $this->set('layoutLang_iso', "/".($lang_iso_1 == 'cs' ? 'cz' : $lang_iso_1));
1881
1882        // html lang
1883        $this->set('html_lang_iso_1', $lang_iso_1);
1884    }
1885
1886    // This will redirect to restriction page if currency not JPY
1887    // return $userdata = user info.
1888    public function jpyOnlyPage($user = '') {
1889        if (!empty($user)) {
1890            $userData = $user;
1891        } elseif (!empty($this->request->query['token'])) {
1892            $token = $this->request->query['token'];
1893            $userData = $this->User->findByApiToken($token);
1894        } else {
1895            return $this->redirect('/mobapp/retrypage');
1896        }
1897
1898        if (isset($userData['User'])) {
1899            $currencyCode = $userData['User']['currency_code'];
1900            $nativeLanguage = isset($userData['User']['native_language2']) ? $userData['User']['native_language2'] : Configure::read('default.user_language');
1901            // null null currency_code in DB is equal to JPY currency as default
1902            if ($currencyCode == '' || $currencyCode == Configure::read('currency_jpy')) {
1903                return $userData;
1904            } else {
1905                $languageCodeIso2 = $this->CountryCode->convertLangIso(array(
1906                    'language_code' => $nativeLanguage,
1907                    'target_iso' => 2
1908                ));
1909
1910                $confLanguage = $this->CountryCode->checkGlobalLanguage(array(
1911                    'language_code' => $nativeLanguage,
1912                    'unset_language_code' => array('ja')
1913                ));
1914
1915                $controller = strtolower($this->params->params['controller']);
1916
1917                if(
1918                    in_array($controller, array('family')) &&
1919                    in_array($currencyCode, Configure::read('family_plan.allowed_currencies')) &&                     
1920                    in_array($nativeLanguage, Configure::read('family_plan.allowed_languages'))
1921                ){
1922                    $confLanguage = $this->CountryCode->checkGlobalLanguage(array(
1923                        'language_code' => $nativeLanguage
1924                    ));
1925                }
1926                
1927                // set the language for translation
1928                if ($confLanguage) {
1929                    $this->Session->write('Config.language', $languageCodeIso2);
1930                } else {
1931                    $this->Session->write('Config.language', 'eng');
1932                }
1933
1934                
1935                // allow access for family plan pages for other languages
1936                if(
1937                    !in_array($controller, array('family')) &&
1938                    !in_array($currencyCode, Configure::read('family_plan.allowed_currencies'))
1939                ){
1940                    return $this->redirect(myTools::getUrl() . '/mobapp/region_restriction');
1941                }
1942            }
1943        } else {
1944            return $this->redirect('/mobapp/retrypage');
1945        }
1946    }
1947
1948    /* this will redirect to restriction page if language and currency not allowed
1949    * check language for non login user 
1950    */
1951    public function checkIfAllowed() {
1952        // disable foreign language if "la" is set
1953       if (isset($this->request->query['la'])) {
1954            $lang = $this->request->query['la'];
1955            if (!empty($lang) && $lang !== Configure::read('default.user_language')) {
1956                //set language
1957                $languageCodeIso2 = $this->CountryCode->convertLangIso(array(
1958                    'language_code' => $lang,
1959                    'target_iso' => 2
1960                ));
1961
1962                $confLanguage = $this->CountryCode->checkGlobalLanguage(array(
1963                    'language_code' => $lang,
1964                    'unset_language_code' => array('ja')
1965                ));
1966
1967                // set the language for translation
1968                if ($confLanguage) {
1969                    $this->Session->write('Config.language', $languageCodeIso2);
1970                } else {
1971                    $this->Session->write('Config.language', 'eng');
1972                }        
1973                return $this->redirect(myTools::getUrl() . '/mobapp/region_restriction');
1974            }
1975        }
1976        // if token is set check user currency
1977        if (isset($this->request->query['token'])) {
1978            $this->jpyOnlyPage();
1979        }
1980    }
1981
1982    /**
1983    * Set memcache timezone
1984    * @param int userId
1985    * @return array ['timezone_id']
1986    */
1987    public function getTimezoneData($userId = NULL) {
1988        $this->loadModel('Timezone');
1989        //initialize memcache
1990        $memcached = new myMemcached();
1991
1992        $timezone = array(
1993            'Timezone' => array(
1994                'id' => Configure::read('default.user_timezone_id'),
1995            )
1996        );
1997
1998        $defaultTimezoneName = Configure::read('default.timezone_name');
1999
2000        $timezoneName = empty($this->request->data['User']['timezone']) ? $defaultTimezoneName : $this->request->data['User']['timezone'];
2001        $tznArr = explode('/', $timezoneName);
2002
2003        //get continents
2004        $continents = array_flip(Configure::read('continents'));
2005
2006        // log and use user current timezone settings if user computer timezone format is incorrect
2007        if (
2008            !isset($tznArr[0]) ||
2009            (isset($tznArr[0]) && !isset($continents[$tznArr[0]]))
2010        ) {
2011            $this->log(__METHOD__ . ' Timezone value format is incorrect. -->' . json_encode($timezoneName) . ' | userId --> ' . json_encode($userId), 'debug');
2012            $userTimezone = NULL;
2013            if ($userId) {
2014                // get user current timezone used
2015                $userTimezone = $this->User->useReplica()->find('first', array(
2016                    'fields' => 'timezone_id',
2017                    'conditions' => array(
2018                        'id' => $userId,
2019                        'timezone_id is not null' 
2020                    ),
2021                    'recursive' => -1
2022                ));
2023            }
2024
2025            $timezoneName = $defaultTimezoneName;
2026            //Configure::read('default.user_timezone_id');
2027
2028            if ($userTimezone) {
2029                $timezoneList = $this->Timezone->getFormattedTimezones();
2030                $usertimezoneDetail = isset($timezoneList[$userTimezone['User']['timezone_id']]) ? $timezoneList[$userTimezone['User']['timezone_id']] : null;
2031
2032                if ($usertimezoneDetail) {
2033                    $timezone['Timezone']['id'] = $userTimezone['User']['timezone_id'];
2034                } else {
2035                    $this->log(__METHOD__ . ' Timezone is not exist in memcached timezone list. -->' . json_encode($userTimezone) . ' | userId --> ' . json_encode($userId), 'debug');
2036                }
2037            }
2038        } else {
2039            $timezone = $this->Timezone->updateTimezoneTable(array('timezoneName' => $timezoneName));
2040        }
2041
2042        if ($timezone) {
2043            $jpTimeDiffData = $this->Timezone->computeTimeDiff(array(
2044                'continent_id' => isset($timezone['Timezone']['continent_id']) ? $timezone['Timezone']['continent_id'] : NULL,
2045                'city' => isset($timezone['Timezone']['city_eng']) ? $timezone['Timezone']['city_eng'] : NULL
2046            ));
2047
2048            if (isset($jpTimeDiffData['success']) && $jpTimeDiffData['success']) {
2049                $this->timeDiff = $jpTimeDiffData['timeDiff'];
2050                $this->utcOffset = $jpTimeDiffData['utc'];
2051            
2052                //save to memcache 
2053                $memcached->set(array(
2054                    'key' => 'user-timediff-' . $userId,
2055                    'value' => array(
2056                        'timeDiff' => $this->timeDiff,
2057                        'utc' => $this->utcOffset
2058                    ),
2059                    'expire' => 604800 //1 week
2060                ));
2061            }
2062
2063            return array(
2064                'timezone_id' => !empty($timezone['Timezone']['id']) ? $timezone['Timezone']['id'] : NULL
2065            );
2066        }
2067
2068        return NULL;
2069    }
2070
2071    /**
2072    * Settle paypal payment receivables
2073    * @param array user data
2074    * @return boolean
2075    */
2076    protected function chargePayPalPaymentReceivable($params = array()) {
2077        //validate need data for payment receivable
2078        if (
2079            empty($params['id']) ||
2080            empty($params['email']) ||
2081            empty($params['currency_code']) ||
2082            empty($params['payment_plan_id']) ||
2083            empty($params['price_id']) ||
2084            empty($params['card_company']) ||
2085            empty($params['paypal_billing_agreement_id'])
2086        )
2087        {
2088            $this->log(__METHOD__ . "error data pass. Data : " . json_encode($params), 'debug');
2089            return false;
2090        }
2091
2092        $userId = $params['id'];
2093        $currencyCode = $params['currency_code'];
2094        $paymentPlanId = $params['payment_plan_id'];
2095        $priceId = $params['price_id'];
2096
2097        // set db connection
2098        $db = ConnectionManager::getDataSource('default');
2099        //db resources reconnect
2100        if ($db->isConnected()) {
2101            $db->close(); // stop
2102        }
2103        $db->reconnect();
2104
2105        $rawQuery = "SELECT 
2106                (SELECT 
2107                        SUM(`amount`) AS `amount`
2108                    FROM
2109                        `payment_receivables`
2110                    WHERE
2111                        `payment_receivables`.`user_id` = u.id
2112                            AND `payment_receivables`.`status` = 0
2113                            AND `payment_receivables`.`payment_element_type` = 1
2114                            AND `payment_receivables`.`created` <= NOW()) AS receivables,
2115                (SELECT 
2116                        SUM(`amount`) AS `amount`
2117                    FROM
2118                        `payment_receivables`
2119                    WHERE
2120                        `payment_receivables`.`user_id` = u.id
2121                            AND `payment_receivables`.`status` = 0
2122                            AND `payment_receivables`.`payment_element_type` = 2
2123                            AND `payment_receivables`.`created` <= NOW()) AS appreciation_receivables,
2124                (SELECT 
2125                        SUM(`amount`) AS `amount`
2126                    FROM
2127                        `payment_receivables`
2128                    WHERE
2129                        `payment_receivables`.`user_id` = u.id
2130                            AND `payment_receivables`.`status` = 0
2131                            AND `payment_receivables`.`payment_element_type` = 3
2132                            AND `payment_receivables`.`created` <= NOW()) AS live_receivables                        
2133            FROM  users AS u WHERE u.id = {$userId}
2134        ";
2135
2136        $result = $this->User->query($rawQuery);
2137
2138        $receivableAmount = isset( $result[0][0]['receivables'] ) && $result[0][0]['receivables'] ? $result[0][0]['receivables'] : 0 ;
2139        $appreciationReceivableAmount = isset( $result[0][0]['appreciation_receivables'] ) && $result[0][0]['appreciation_receivables'] ? $result[0][0]['appreciation_receivables'] : 0 ;
2140        $liveReceivableAmount = isset( $result[0][0]['live_receivables'] ) && $result[0][0]['live_receivables'] ? $result[0][0]['live_receivables'] : 0 ;
2141        $totalReceivableAmount = $receivableAmount + $appreciationReceivableAmount + $liveReceivableAmount;
2142
2143        // check payment receivable
2144        if ( $totalReceivableAmount < 1 ) {
2145            $this->log(__METHOD__ . "::No payment receivable. \n Data : " . json_encode($params), 'debug');
2146            return false;
2147        }
2148
2149        //generate ordd code
2150        $paymentHash = myTools::generateOrderCode($userId);
2151        $membershipStatusIndex = UserTable::getStudentMembershipStatus($userId);
2152        // Reservation payment transaction 
2153        if( $receivableAmount > 0 ) {
2154
2155            $paymentParams = array(
2156                'currencyCode' => $currencyCode,
2157                'formType' => Configure::read('payment_credit_receivable'),
2158                'paymentType' => Configure::read('payment_types.payment_receivable'),
2159                'logFileName' => 'debug',
2160                'paymentAmount' => $receivableAmount,
2161                'priceId' => $priceId,
2162                'paymentPlanId' => $paymentPlanId
2163            );
2164
2165            $ptParams = array(
2166                'user_id' => $userId,
2167                'payment_hash' => $paymentHash,
2168                'course_id' => Configure::read("credit.course_id"),
2169                'payment_params' => json_encode($paymentParams),
2170            );
2171
2172            // create payment transaction
2173            if (!$pt = $this->PaymentTransaction->setWPPaymentTransaction($ptParams)) {
2174                $this->log(__METHOD__ . "::Cannot create payment transaction. \nData:" .json_encode($ptParams), 'debug');
2175                return false;
2176            }
2177            
2178        }
2179        // Appreciation payment transaction
2180        if( $appreciationReceivableAmount > 0 ) {
2181
2182            $paymentParams = array(
2183                'currencyCode' => $currencyCode,
2184                'formType' => Configure::read('payment_credit_appreciation_receivable'),
2185                'paymentType' => Configure::read('payment_types.payment_receivable'),
2186                'logFileName' => 'debug',
2187                'paymentAmount' => $appreciationReceivableAmount,
2188                'priceId' => $priceId,
2189                'paymentPlanId' => $paymentPlanId
2190            );
2191
2192            $ptParams = array(
2193                'user_id' => $userId,
2194                'payment_hash' => $paymentHash,
2195                'course_id' => Configure::read("credit.course_id"),
2196                'payment_params' => json_encode($paymentParams),
2197            );
2198
2199            // create payment transaction
2200            if (!$apt = $this->PaymentTransaction->setWPPaymentTransaction($ptParams)) {
2201                $this->log(__METHOD__ . "::Cannot create payment transaction. \nData:" .json_encode($ptParams), 'debug');
2202                return false;
2203            }
2204
2205        }
2206
2207        // Live payment transaction
2208        if ($liveReceivableAmount > 0) {
2209
2210            $paymentParams = array(
2211                'currencyCode' => $currencyCode,
2212                'formType' => Configure::read('payment_live_lesson_receivable'),
2213                'paymentType' => Configure::read('payment_types.payment_receivable'),
2214                'logFileName' => 'debug',
2215                'paymentAmount' => $liveReceivableAmount,
2216                'priceId' => $priceId,
2217                'paymentPlanId' => $paymentPlanId
2218            );
2219
2220            $ptParams = array(
2221                'user_id' => $userId,
2222                'payment_hash' => $paymentHash,
2223                'course_id' => Configure::read("credit.course_id"),
2224                'payment_params' => json_encode($paymentParams),
2225            );
2226
2227            // create payment transaction
2228            if (!$lpt = $this->PaymentTransaction->setWPPaymentTransaction($ptParams)) {
2229                $this->log(__METHOD__ . "::Cannot create payment transaction. \nData:" .json_encode($ptParams), 'debug');
2230                return false;
2231            }
2232        }
2233
2234        //db resources reconnect
2235        if ($db->isConnected()) {
2236            $db->close(); // stop
2237        }
2238        $db->reconnect();
2239
2240        // load PayPal class
2241        if (!class_exists('PayPal')) {
2242            App::import('Lib', 'PayPal');
2243        }
2244
2245        $paypal = new PayPal();
2246
2247        // get access token data
2248        $accessTokenData = $paypal->getAccessToken();
2249
2250        // return if error
2251        if (isset($accessTokenData['error'])) {
2252            $this->log(__METHOD__ . ' error -->' . json_encode($accessTokenData) . "\n | params --> " . json_encode($params), 'debug');
2253            return false;
2254        }
2255
2256        $createOrderParams = array(
2257            'accessToken' => $accessTokenData['access_token'],
2258            'paypalRequestId' => (isset($pt['id']) && $pt['id']) ? $pt['id'] : (isset($apt['id']) ? $apt['id'] : $lpt['id']),
2259            'intent' => 'CAPTURE',
2260            'paymentHash' => $paymentHash,
2261            'userId' => $userId,
2262            'currencyCode' => $currencyCode,
2263            'amount' => (int)$totalReceivableAmount,
2264            'billingAgreementId' => $params['paypal_billing_agreement_id']
2265        );
2266
2267        // void authorization
2268        $orderResult = $paypal->createOrder($createOrderParams);
2269        $paymentSuccess = isset($orderResult['status']) && $orderResult['status'] == 'COMPLETED' ? true : false;
2270        $this->loadModel('Payment');
2271
2272        // Reservation payment
2273        if( $receivableAmount > 0 ) {
2274            $savePaymentArr = array(
2275                'user_id' => $userId,
2276                'type_id' => 2,
2277                'pay_kbn' => 1,
2278                'reference_id' => $userId,
2279                'payment_transaction_password' => $paymentSuccess ? $pt['password'] : '',
2280                'status' => $paymentSuccess ? 1 : '',
2281                'form_type' => Configure::read('payment_credit_receivable'),
2282                'ordd' => $paymentSuccess ? $paymentHash : '',
2283                'amount' => $receivableAmount,
2284                'param1' => json_encode($orderResult),
2285                'param2' => $paymentSuccess ? '' : 'error',
2286                'card_company' => Configure::read('card_company.paypal'),
2287                'transaction_code' => $paymentSuccess ? $paymentHash : '',
2288                'currency_id' => Configure::read('default.settlement_currency_id'),
2289                'currency_code' => $currencyCode,
2290                'payment_id' => $paymentPlanId,
2291                'price_id' => $priceId,
2292                'payment_type' => Configure::read('payment_types.payment_receivable'),
2293                'logFileName' => 'debug'
2294            );
2295
2296            // create new payment
2297            $paymentSave = $this->Payment->rawSavePayment($savePaymentArr);
2298        }
2299
2300        // Appreciation payment
2301        if( $appreciationReceivableAmount > 0 ) {
2302            $savePaymentArr = array(
2303                'user_id' => $userId,
2304                'type_id' => 2,
2305                'pay_kbn' => 1,
2306                'reference_id' => $userId,
2307                'payment_transaction_password' => $paymentSuccess ?($pt['password'] ?? ''): '',
2308                'status' => $paymentSuccess ? 1 : '',
2309                'form_type' => Configure::read('payment_credit_appreciation_receivable'),
2310                'ordd' => $paymentSuccess ? $paymentHash : '',
2311                'amount' => $appreciationReceivableAmount,
2312                'param1' => json_encode($orderResult),
2313                'param2' => $paymentSuccess ? '' : 'error',
2314                'card_company' => Configure::read('card_company.paypal'),
2315                'transaction_code' => $paymentSuccess ? $paymentHash : '',
2316                'currency_id' => Configure::read('default.settlement_currency_id'),
2317                'currency_code' => $currencyCode,
2318                'payment_id' => $paymentPlanId,
2319                'price_id' => $priceId,
2320                'payment_type' => Configure::read('payment_types.payment_receivable'),
2321                'logFileName' => 'debug'
2322            );
2323
2324            // create new payment
2325            $paymentSave = $this->Payment->rawSavePayment($savePaymentArr);
2326        }
2327
2328        // Live payment
2329        if( $liveReceivableAmount > 0 ) {
2330            $savePaymentArr = array(
2331                'user_id' => $userId,
2332                'type_id' => 2,
2333                'pay_kbn' => 1,
2334                'reference_id' => $userId,
2335                'payment_transaction_password' => $paymentSuccess ? ($pt['password'] ?? '') : '',
2336                'status' => $paymentSuccess ? 1 : '',
2337                'form_type' => Configure::read('payment_live_lesson_receivable'),
2338                'ordd' => $paymentSuccess ? $paymentHash : '',
2339                'amount' => $liveReceivableAmount,
2340                'param1' => json_encode($orderResult),
2341                'param2' => $paymentSuccess ? '' : 'error',
2342                'card_company' => Configure::read('card_company.paypal'),
2343                'transaction_code' => $paymentSuccess ? $paymentHash : '',
2344                'currency_id' => Configure::read('default.settlement_currency_id'),
2345                'currency_code' => $currencyCode,
2346                'payment_id' => $paymentPlanId,
2347                'price_id' => $priceId,
2348                'payment_type' => Configure::read('payment_types.payment_receivable'),
2349                'logFileName' => 'debug'
2350            );
2351
2352            // create new payment
2353            $paymentSave = $this->Payment->rawSavePayment($savePaymentArr);
2354        }        
2355
2356        if ($paymentSave && $paymentSuccess) {
2357
2358            // Update Reservation payment receivables
2359            if( $receivableAmount > 0 ) {
2360                // get payment id
2361                $paymentData = $this->Payment->find('first', array(
2362                    'fields' => array(),
2363                    'conditions' => array(
2364                        'user_id' => $userId,
2365                        'form_type' => Configure::read('payment_credit_receivable'),
2366                        'ordd' => $paymentHash
2367                    ),
2368                    'recursive' => -1
2369                ));
2370
2371                if ($paymentData) {
2372                    $this->loadModel('PaymentReceivable');
2373                    // set payment receivable statuses to 2 - received
2374                    $this->PaymentReceivable->updateReceivableReservationPayment(
2375                        $userId,
2376                        array(
2377                            'status' => 2,
2378                            'payment_id' => $paymentData['Payment']['id'],
2379                            'payment_collection_date' => date("Y-m-d H:i:s"),
2380                            'card_company' => Configure::read('card_company.paypal'),
2381                            'payment_plan_id' => $paymentPlanId,
2382                            'membership_type_index' => $membershipStatusIndex
2383                        ),
2384                        array(
2385                            'PaymentReceivable.user_id' => $userId,
2386                            'PaymentReceivable.status' => 0,
2387                            'PaymentReceivable.payment_element_type' => 1,
2388                            'PaymentReceivable.created <=' => date('Y-m-d H:i:s')
2389                        )
2390                    );
2391                }
2392            }
2393
2394            // Update Appreciation payment receivables
2395            if( $appreciationReceivableAmount > 0 ) {
2396                // get payment id
2397                $paymentData = $this->Payment->find('first', array(
2398                    'fields' => array(),
2399                    'conditions' => array(
2400                        'user_id' => $userId,
2401                        'form_type' => Configure::read('payment_credit_appreciation_receivable'),
2402                        'ordd' => $paymentHash
2403                    ),
2404                    'recursive' => -1
2405                ));
2406
2407                if ($paymentData) {
2408                    $this->loadModel('PaymentReceivable');
2409                    // set payment receivable statuses to 2 - received
2410                    $this->PaymentReceivable->updateReceivableReservationPayment(
2411                        $userId,
2412                        array(
2413                            'status' => 2,
2414                            'payment_id' => $paymentData['Payment']['id'],
2415                            'payment_collection_date' => date("Y-m-d H:i:s"),
2416                            'card_company' => Configure::read('card_company.paypal'),
2417                            'payment_plan_id' => $paymentPlanId,
2418                            'membership_type_index' => $membershipStatusIndex
2419                        ),
2420                        array(
2421                            'PaymentReceivable.user_id' => $userId,
2422                            'PaymentReceivable.status' => 0,
2423                            'PaymentReceivable.payment_element_type' => Configure::read('appreciation_data.payment_element_type'),
2424                            'PaymentReceivable.created <=' => date('Y-m-d H:i:s')
2425                        )
2426                    );
2427                }
2428            }
2429
2430            // Update live payment receivables
2431            if( $liveReceivableAmount > 0 ) {
2432                // get payment id
2433                $paymentData = $this->Payment->find('first', array(
2434                    'fields' => array(),
2435                    'conditions' => array(
2436                        'user_id' => $userId,
2437                        'form_type' => Configure::read('payment_live_lesson_receivable'),
2438                        'ordd' => $paymentHash
2439                    ),
2440                    'recursive' => -1
2441                ));
2442
2443                if ($paymentData) {
2444                    $this->loadModel('PaymentReceivable');
2445                    // set payment receivable statuses to 2 - received
2446                    $this->PaymentReceivable->updateReceivableReservationPayment(
2447                        $userId,
2448                        array(
2449                            'status' => 2,
2450                            'payment_id' => $paymentData['Payment']['id'],
2451                            'payment_collection_date' => date("Y-m-d H:i:s"),
2452                            'card_company' => Configure::read('card_company.paypal'),
2453                            'payment_plan_id' => $paymentPlanId,
2454                            'membership_type_index' => $membershipStatusIndex                            
2455                        ),
2456                        array(
2457                            'PaymentReceivable.user_id' => $userId,
2458                            'PaymentReceivable.status' => 0,
2459                            'PaymentReceivable.payment_element_type' => 3,
2460                            'PaymentReceivable.created <=' => date('Y-m-d H:i:s')
2461                        )
2462                    );
2463                }
2464            }            
2465
2466        }
2467        if( isset($pt['id']) ) {
2468            $ptUpdateParams = array(
2469                'id' => $pt['id'],
2470                'fields' => array(
2471                    'status' => $paymentSuccess ? 1 : 2,
2472                    'response_text' => $orderResult
2473                ),
2474                'logFileName' => 'debug'
2475            );
2476
2477            // update payment transaction
2478            if (!$this->PaymentTransaction->updateWPPaymentTransaction($ptUpdateParams)) {
2479                $this->log(__METHOD__ . ' Cannot update payment transaction. --> ' . json_encode($ptUpdateParams), 'debug');
2480            }
2481        }
2482
2483        if( isset($apt['id']) ) {
2484            $ptUpdateParams = array(
2485                'id' => $apt['id'],
2486                'fields' => array(
2487                    'status' => $paymentSuccess ? 1 : 2,
2488                    'response_text' => $orderResult
2489                ),
2490                'logFileName' => 'debug'
2491            );
2492            // update payment transaction
2493            if (!$this->PaymentTransaction->updateWPPaymentTransaction($ptUpdateParams)) {
2494                $this->log(__METHOD__ . ' Cannot update payment transaction. --> ' . json_encode($ptUpdateParams), 'debug');
2495            }
2496        }
2497
2498        if( isset($lpt['id']) ) {
2499            $ptUpdateParams = array(
2500                'id' => $lpt['id'],
2501                'fields' => array(
2502                    'status' => $paymentSuccess ? 1 : 2,
2503                    'response_text' => $orderResult
2504                ),
2505                'logFileName' => 'debug'
2506            );
2507            // update payment transaction
2508            if (!$this->PaymentTransaction->updateWPPaymentTransaction($ptUpdateParams)) {
2509                $this->log(__METHOD__ . ' Cannot update payment transaction. --> ' . json_encode($ptUpdateParams), 'debug');
2510            }
2511        }        
2512
2513        // log
2514        $this->log(__METHOD__ . "::PaymentReceivable charge on withdrawal. \nData: " . json_encode(array('params' => $params, 'result' => $orderResult)), 'debug');
2515    }
2516
2517    /**
2518    * Settle payment receivables 
2519    * @param array user data
2520    * @return boolean
2521    */
2522    protected function chargePaymentReceivable($params = array()) {
2523        //validate need data for payment receivable
2524        if (
2525            empty($params['id']) ||
2526            empty($params['email']) ||
2527            empty($params['currency_code']) ||
2528            empty($params['payment_plan_id']) ||
2529            empty($params['price_id']) ||
2530            empty($params['card_company']) 
2531        )
2532        {
2533            $this->log(__METHOD__ . "error data pass. Data : " . json_encode($params), 'debug');
2534            return false;
2535        }
2536
2537        $userId = $params['id'];
2538        $currencyCode = $params['currency_code'];
2539        $paymentPlanId = $params['payment_plan_id'];
2540        $priceId = $params['price_id'];
2541
2542        // set db connection
2543        $db = ConnectionManager::getDataSource('default');
2544        //db resources reconnect
2545        if ($db->isConnected()) {
2546            $db->close(); // stop
2547        }
2548        $db->reconnect();        
2549
2550        $rawQuery = "
2551            SELECT 
2552                SUM(`amount`) as `amount`
2553            FROM
2554                `payment_receivables`
2555            WHERE
2556                `payment_receivables`.`user_id` = {$userId}
2557                AND `payment_receivables`.`status` = 0
2558                AND `payment_receivables`.`payment_element_type` IN (1 , 2, 3)
2559                AND `payment_receivables`.`created` <= NOW();
2560        ";
2561        $result = $this->User->query($rawQuery);
2562
2563        //check payment receivable
2564        if (!isset($result[0][0]['amount']) || empty($result[0][0]['amount'])) {
2565            $this->log(__METHOD__ . "::No payment receivable. \n Data : " . json_encode($params), 'debug');
2566            return false;
2567        }
2568
2569        //get payment receivable
2570        $receivablePayment = $result[0][0]['amount'];        
2571
2572        //generate ordd code
2573        $paymentHash = myTools::generateOrderCode($userId);
2574        $familyId = null;
2575
2576        $paymentParams = array(
2577            'currencyCode' => $currencyCode,
2578            'formType' => Configure::read('payment_credit_receivable'),
2579            'paymentType' => Configure::read('payment_types.payment_receivable'),
2580            'logFileName' => 'debug',
2581            'paymentAmount' => $receivablePayment,
2582            'familyId' => $familyId,
2583            'priceId' => $priceId,
2584            'paymentPlanId' => $paymentPlanId
2585        );
2586
2587        // if corporate user
2588        if (isset($params['corporate_id'])) {
2589            $paymentParams['corporateSettlementType'] = Configure::read('corporate_settlement_types.receivable_reservation_payment');
2590        }
2591
2592        $ptParams = array(
2593            'userId' => $userId,
2594            'status' => 0,
2595            'paymentHash' => $paymentHash,
2596            'paymentParams' => json_encode($paymentParams),
2597            'responseText' => '',
2598            'logFileName' => 'debug'
2599        );
2600
2601        //db resources reconnect
2602        if ($db->isConnected()) {
2603            $db->close(); // stop
2604        }
2605        $db->reconnect();
2606
2607        // create payment transaction
2608        if (!$pt = $this->PaymentTransaction->rawSaveCronPaymentTransaction($ptParams)) {
2609            $this->log(__METHOD__ . "::Cannot create payment transaction. \nData:" .json_encode($ptParams), 'debug');
2610            return false;            
2611        }
2612
2613        //db resources reconnect
2614        if ($db->isConnected()) {
2615            $db->close(); // stop
2616        }
2617        $db->reconnect();
2618
2619        //default user data
2620        $clientIp = PaymentTable::getClientIpByCompanyId($params['card_company']);
2621        $email = $params['email'];
2622        $sendId = $params['id'];
2623
2624        //set payment data
2625        $params = array(
2626            'clientIp' => $clientIp,
2627            'email' => $email,
2628            'sendId' => $sendId,
2629            'money' => $receivablePayment,
2630            'paymentHash' => $paymentHash
2631        );    
2632
2633        $fallBackPayment = ZChargeComponent::charge_with_regsterd_card(json_encode($params));
2634
2635        // log
2636        $this->log(__METHOD__ . "::PaymentReceivable charge on withdrawal. \nData: " . json_encode(array('params' => $params, 'result' => $fallBackPayment)), 'debug');
2637    }
2638
2639    /**
2640    * Charge worlplay users on withdraw
2641    * @param array - user data
2642    * @return boolean
2643    */
2644    protected function wpChargePaymentReceivable($params = array()) {
2645        if (
2646            empty($params['id']) ||
2647            empty($params['email']) ||
2648            empty($params['currency_code']) ||
2649            empty($params['payment_plan_id']) ||
2650            empty($params['price_id']) ||
2651            empty($params['card_token'])
2652        ) {
2653            $this->log(__METHOD__ . "::Missing parameters. \nData : ". json_encode($params), 'debug');
2654            return false;
2655        }
2656
2657        // set db connection
2658        $db = ConnectionManager::getDataSource('default');
2659
2660        //db resources reconnect
2661        if ($db->isConnected()) {
2662            $db->close(); // stop
2663        }
2664        $db->reconnect();        
2665
2666        $userId = $params['id'];
2667
2668        $rawQuery = "SELECT 
2669                (SELECT 
2670                        SUM(`amount`) AS `amount`
2671                    FROM
2672                        `payment_receivables`
2673                    WHERE
2674                        `payment_receivables`.`user_id` = u.id
2675                            AND `payment_receivables`.`status` = 0
2676                            AND `payment_receivables`.`payment_element_type` in (1,2,3)
2677                            AND `payment_receivables`.`created` <= NOW()) AS receivables
2678            FROM  users AS u WHERE u.id = {$userId}
2679        ";
2680
2681        $result = $this->User->query($rawQuery);
2682
2683        $totalReceivableAmount = isset( $result[0][0]['receivables'] ) && $result[0][0]['receivables'] ? $result[0][0]['receivables'] : 0 ;
2684
2685        //check payment receivable
2686        if ( $totalReceivableAmount < 1 ) {
2687            $this->log(__METHOD__ . "::No payment receivable. \n Data : " . json_encode($params), 'debug');
2688            return false;
2689        }      
2690
2691        $email = $params['email'];
2692        $currencyCode = $params['currency_code'];
2693        $paymentPlanId = $params['payment_plan_id'];
2694        $priceId = $params['price_id'];
2695        $receivableFormType = Configure::read('payment_credit_receivable');
2696        $currencyExponents = Configure::read('worldpay.currency_exponents');
2697        $receivableOrderCode = myTools::generateOrderCode($userId);
2698        $paymentMethodType = myTools::getWPPaymentMethodType($params['card_brand'], 'payment');
2699        $merchantCode = myTools::getWPMerchantCode($paymentMethodType);
2700        $paymentMethod = explode('_', $paymentMethodType);
2701        $paymentMethod = isset($paymentMethod[0]) ? $paymentMethod[0] : null;
2702        $paymentPlanId = $paymentPlanId;
2703        $exponent = $currencyExponents[$currencyCode];
2704
2705        $receivablPaymentAmountArr = myTools::wpGetAmount($exponent, (float)$totalReceivableAmount);
2706        $ncAmount = $receivablPaymentAmountArr['ncAmount'];
2707        $wpAmount = $receivablPaymentAmountArr['wpAmount'];
2708        $membershipStatusIndex = UserTable::getStudentMembershipStatus($userId);
2709
2710        // Appreciation and Reservation payment transaction
2711        if( $totalReceivableAmount > 0 ) {
2712            $ptParams = array(
2713                'userId' => $userId,
2714                'status' => 0,
2715                'paymentHash' => $receivableOrderCode,
2716                'paymentParams' => json_encode(array(
2717                    'currencyCode' => $currencyCode,
2718                    'formType' => $receivableFormType,
2719                    'paymentType' => Configure::read('payment_types.payment_receivable'),
2720                    'logFileName' => 'debug',
2721                    'wpPaymentAmount' => $wpAmount,
2722                    'paymentAmount' => $ncAmount,
2723                    'cronDateRun' => $this->cronDateTime,
2724                    'priceId' => $priceId,
2725                    'paymentPlanId' => $paymentPlanId,
2726                    'merchantCode' => $merchantCode,
2727                    'membershipStatusIndex' => $membershipStatusIndex
2728                )),
2729                'responseText' => '',
2730                'logFileName' => 'debug'
2731            );
2732
2733            // create payment transaction
2734            if (!$pt = $this->PaymentTransaction->rawSaveCronPaymentTransaction($ptParams)) {
2735                $this->log(__METHOD__ . "::Cannot create payment transaction. \nData:" .json_encode($ptParams), 'debug');
2736                return false;
2737            }
2738        }
2739
2740        //set payment params
2741        $chargeParams = array(
2742            'merchantCode' => $merchantCode,
2743            'orderCode' => $receivableOrderCode,
2744            'description' => 'Payment Credit Receivable',
2745            'currencyCode' => $currencyCode,
2746            'exponent' => $exponent,
2747            'amount' => $wpAmount,
2748            'cardToken' => $params['card_token'],
2749            'email' => $email,
2750            'authenticatedShopperId' => $userId,
2751            'xmlName' => 'direct_payment_with_token',
2752            'shopperIpAddress' => '52.193.149.250', // ncweb6 server ip address
2753            'wpTransactionIdentifier' => $params['wp_transaction_identifier'],
2754            'paymentMethod' => $paymentMethod
2755        );        
2756
2757        $receivableResult = wpPaymentService::directPayment($chargeParams);
2758
2759        //check direct payment result
2760        if (!myTools::checkIfWPPaymentResponseIsAuthorised($receivableResult)) {
2761            $receivableStatus = 2; // error
2762        }
2763
2764        //db resources reconnect
2765        if ($db->isConnected()) {
2766            $db->close(); // stop
2767        }
2768        $db->reconnect();     
2769
2770        $this->PaymentTransaction->rawCronUpdatePaymentTransactionResponseTextAndStatus(array(
2771            'orderCode' => $receivableOrderCode,
2772            'responseText' => json_encode(array('cronMonthlyPaymentReceivable_response' => $receivableResult)),
2773            'status' => isset($receivableStatus) ? $receivableStatus : 2, // 1 - success, 2 - error
2774            'logFileName' => 'debug'
2775        ));
2776    }
2777
2778    public function setSeoLocalizeUrl() {
2779        $hasLocalizeSupport = true; // default
2780        $con = $this->params->params['controller'];
2781        $action = $this->params->params['action'];
2782
2783        // add controller and/or action for the web pages that will not be applied in the tags for SEO
2784        // if ($con == 'MyPage' && $action == 'index') { // --> this is just a sample
2785        //     $hasLocalizeSupport = false;
2786        // }
2787
2788        if (!$hasLocalizeSupport || $this->localizeDir == Configure::read('default.user_language')) {
2789            $seoLocalizeUrl = myTools::getUrl();
2790        } else {
2791            $seoLocalizeUrl = myTools::getUrl() . '/' . $this->localizeDir;
2792        }
2793
2794        $this->set('hasLocalizeSupport', $hasLocalizeSupport);
2795        $this->set('seoLocalizeUrl', $seoLocalizeUrl);
2796    }
2797
2798    /**
2799     * get currency code using user's currency code or local language directory currency code equivalent.
2800     */
2801    public function getCustomCurrencyCode() {
2802        return isset($this->sharedUserData['User']['currency_code']) ? $this->sharedUserData['User']['currency_code'] : (isset($this->localizeDir) && is_string($this->localizeDir) && isset($this->allowedCurrencies[$this->localizeDir]) ? $this->allowedCurrencies[$this->localizeDir] : Configure::read('default.user_currency'));
2803    }
2804
2805    /**
2806     * get premium plan price
2807     */
2808    public function getPremiumPlanPrice($params = []) {
2809        $logFileName = isset($params['logFileName']) ? $params['logFileName'] : null;
2810        $currencyCode = isset($params['currencyCode']) ? $params['currencyCode'] : null;
2811        $numberFormatFlg = isset($params['numberFormatFlg']) ? $params['numberFormatFlg'] : true;
2812        if (!isset($currencyCode)) {
2813            $currencyCode = $this->getCustomCurrencyCode();
2814        }
2815
2816
2817        $this->loadModel('PaymentPlanPrice');
2818        $amount = $this->PaymentPlanPrice->getMonthlyPrice(array(
2819            'currencyCode' => $currencyCode,
2820            'paymentPlanId' => Configure::read('payment_plans.premium_plan'),
2821            'numberFormatFlg' => $numberFormatFlg,
2822            'logFileName' => $logFileName
2823        ));
2824
2825        return $amount;
2826    }
2827
2828    /**
2829     * NC-7922: Stasapu cs admin domains not allowed access on user
2830    */
2831    private function checkStasapuDomain() {
2832        $env = Configure::read('ENVIRONMENT');
2833        $stasapuDomainArr = Configure::read('stasapucs_host');
2834        $getDomainArr = parse_url($_SERVER['HTTP_HOST']);
2835        $host = isset($getDomainArr['path']) ? $getDomainArr['path'] : null;
2836        if ( isset($stasapuDomainArr[$env]) && $host ) {
2837            if ( $host == $stasapuDomainArr[$env] ) {
2838                throw new NotFoundException();
2839            }
2840        }
2841    }
2842
2843    public function disablePageForSapuri($page='pc') {
2844        if ($page == 'pc' && $this->Auth->loggedIn() && $this->isStudySapuriUser) {
2845            return $this->isStudySapuriTosUser ? $this->redirect('/lesson-reservation') : $this->redirect('/mypage');
2846        }
2847
2848        if ($page == 'mobapp' && isset($this->request->query['token']) && $this->isStudySapuriUser) {
2849            // return $this->redirect('/mobapp/close?token='.$this->request->query['token']);
2850            return $this->redirect('/?plan=not_supported'.$this->request->query['token']);
2851        }
2852    }
2853    /**
2854     * block free user from sapuri toS student
2855     */
2856    public function blockWithdrawnSapuriToS($page = 'pc') {
2857        $token = !empty($this->request->query['token']) ? $this->request->query['token'] : null;
2858        $userId = null;
2859        $checkRes = [];
2860
2861        if ($page == 'mobapp' && $token) {
2862            $user = UserTable::validToken($token);
2863            $userId = isset($user['User']['id']) ? $user['User']['id'] : $userId;
2864        }
2865
2866        if ($page == 'pc' && $this->Auth->loggedIn()) {
2867            $userId = $this->Auth->user('id');
2868        }
2869
2870        if ($userId) {
2871            $usersExtend = ClassRegistry::init('UsersExtend');
2872            $usersExtend->openDBReplica();
2873            $checkRes = $usersExtend->find('first', [
2874                'conditions' => ['UsersExtend.user_id' => $userId]
2875            ]);
2876            $usersExtend->closeDBReplica();
2877        }
2878        $this->log(__METHOD__ . "::Check if user is sapuri tos student. \nData: " . json_encode(['userId' => $userId, 'checkRes' => $checkRes]), 'error');
2879        if (isset($checkRes) && count($checkRes)) {
2880            $redirectUrl = ($page == 'mobapp') ? '/mobapp/close?token='.$token : '/mypage';
2881            return $this->redirect($redirectUrl);
2882        }
2883    }
2884
2885    /**
2886     * NC-8916: create english hub cookie
2887    */
2888    private function createEnglishHubCookie() {
2889        $indexCookieStr = null;
2890        $p = "";
2891        $cid = "";
2892        
2893        // check cid and p params for ehub
2894        if ( 
2895                ( isset($this->request->query['cid']) && $this->request->query['cid'] ) && 
2896                ( isset($this->request->query['p']) && $this->request->query['p'] )
2897            )
2898        {
2899            $cid = $this->request->query['cid'];
2900            $p = $this->request->query['p'];
2901            
2902            // create index
2903            $indexCookieStr = "CL_".$p;
2904            $this->Cookie->write($indexCookieStr, $cid, false, Configure::read("cookieTime"));
2905        }
2906
2907        // check if campaign code for english hub is not set but english hub params are present
2908        if ( 
2909            // - if has index
2910            $indexCookieStr && 
2911            
2912            // - if current campaign_code is not from english hub
2913            ( 
2914                !$this->Cookie->check('campaign_code') || 
2915                
2916                // - has cookie data, but not enlish_hub cookie
2917                ( 
2918                    $this->Cookie->check('campaign_code') && 
2919                    $this->Cookie->read('campaign_code') != Configure::read("english_hub_affiliate_cc") 
2920                )
2921            )
2922            
2923            // - if from affee -> do not run campaign_code
2924            && $p != "phdiu0vd8jvm"
2925        ) {
2926            // create english hub cookie
2927            $this->Cookie->write('campaign_code',Configure::read("english_hub_affiliate_cc"), true, Configure::read("cookieTime") );
2928        }
2929        
2930        return $indexCookieStr;
2931    }
2932
2933    public function checkControllerActionExist($controller, $action) {
2934        $controller = Inflector::camelize($controller);
2935        $m_controller = $controller.'Controller';
2936        App::import('Controller', $m_controller);
2937
2938        if (!class_exists($m_controller)) return false;
2939
2940        $aMethods = get_class_methods($m_controller);
2941        if ($aMethods) {
2942            foreach ($aMethods as $idx => $method) {
2943                if($action==$method) return true;
2944            }
2945        } else  {
2946            //this is probably NOT a controller!
2947        }
2948        return false;
2949    }
2950
2951    /**
2952     * NC-9586: check if from SNS share
2953    */
2954    public function checkIfSNSShare(){
2955        if(
2956            isset($_GET["nc_share_ref"]) &&
2957            $_GET["nc_share_ref"] == "nc_sns_share" &&
2958            isset($_SERVER["HTTP_USER_AGENT"]) && 
2959            (
2960                (strpos($_SERVER["HTTP_USER_AGENT"], 'facebookexternalhit') !== false) ||
2961                (strpos($_SERVER["HTTP_USER_AGENT"], 'Twitterbot') !== false) ||
2962                (strpos($_SERVER["HTTP_USER_AGENT"], 'line-poker') !== false)
2963            )
2964        ){
2965            return true;
2966        }
2967
2968        return false;
2969    }
2970
2971
2972    /**
2973    * fetch user's appreciation options data for modal display
2974    * @param : array( 'chat_hash' => str )
2975    * @return : array( 'html_element' => str[html element] )
2976    */
2977    public function setUpAppreciationSelectionModalElement( $params = array() ) {
2978        $result = array();
2979        $chatHash = isset($params['chat_hash']) && $params['chat_hash'] ? $params['chat_hash'] : null ;
2980        if ( $chatHash ) {
2981
2982            $fetchAppreciationData = $this->LessonOnairsLog->fetchAppreciationOptionToTeacher(array( 'chat_hash' => $chatHash));
2983            if( 
2984                (isset($fetchAppreciationData['data']) && $fetchAppreciationData['data']) && 
2985                (
2986                    (isset($fetchAppreciationData['user_tips_appreciation_flg']) && $fetchAppreciationData['user_tips_appreciation_flg'] == 1) ||
2987                    (isset($fetchAppreciationData['user_message_appreciation_flg']) && $fetchAppreciationData['user_message_appreciation_flg'] == 1)
2988                )
2989            ) { // check data option available user_appreciation_flg
2990                $appreciationGroupAmountLogDataArr = $fetchAppreciationData['data'];
2991                $teacherteacherDataObj= new TeacherTable($fetchAppreciationData['teacher_data']);
2992
2993                // set default details var, normal teacher
2994                $_name = $teacherteacherDataObj->name;
2995                $_jp_name = $teacherteacherDataObj->jp_name;
2996                $_image_url = $teacherteacherDataObj->getImageUrl();
2997
2998                // if counselor teacher, set details var for counselor
2999                if(isset($teacherteacherDataObj->counseling_flg) && $teacherteacherDataObj->counseling_flg){
3000                    // get counselor default img
3001                    $counselorImageUrl = $teacherteacherDataObj->getProfileImage(Configure::read('default_counselor_detail'));
3002
3003                    // counselor data
3004                    $_name = 'Counselor';
3005                    $_jp_name = 'カウンセラー';
3006                    $_image_url = $counselorImageUrl['image_url'];
3007                }
3008
3009                // if avatar teacher, set details var for avatar parent
3010                if (
3011                    (isset($teacherteacherDataObj->avatar_id) && $teacherteacherDataObj->avatar_id) && 
3012                    (isset($teacherteacherDataObj->avatar_flg) && $teacherteacherDataObj->avatar_flg)
3013                ) {
3014                    // avatar parent data
3015                    $_name = $teacherteacherDataObj->getAvatarParentNameEn();
3016                    $_jp_name =  $teacherteacherDataObj->getAvatarParentName();
3017                    $_image_url = $teacherteacherDataObj->getAvatarParentImageUrl();
3018                }
3019
3020                // set teacher data for view
3021                $teacherData = array(
3022                    'id' => $teacherteacherDataObj->id,
3023                    'name' => $_name,
3024                    'jp_name' => $_jp_name,
3025                    'image_url' => $_image_url
3026                );
3027
3028                // - user data obj
3029                $userData = new UserTable($this->sharedUserData['User']);
3030
3031                // - user appreciation message/tips behavior NJ-53624
3032                $getTeacherCoinBoxData = $this->TeacherCoinBox->isHashExists($params['chat_hash'], $this->Auth->user('id'));
3033                $element_message = '';
3034                $tipShow = $fetchAppreciationData['user_tips_appreciation_flg'];
3035                $has_no_tips_yet = 1;
3036                if (!empty($getTeacherCoinBoxData)){
3037                    $element_message = $getTeacherCoinBoxData['TeacherCoinBox']['element_message'];
3038                    $has_no_tips_yet = $getTeacherCoinBoxData['TeacherCoinBox']['has_tips'] == 1 ? 0 : 1;
3039                }
3040                $finalTipShow = $tipShow == 1 ? $has_no_tips_yet : $tipShow;
3041                $view = new View($this, false);
3042                $appreciation_selection_modal_params = array(
3043                    'element_message' => $element_message,
3044                    'optionArr' => $appreciationGroupAmountLogDataArr,
3045                    'teacherArr' => $teacherData,
3046                    'chat_hash' => $chatHash,
3047                    'user_tips_appreciation_flg' => $finalTipShow,
3048                    'user_message_appreciation_flg' => $fetchAppreciationData['user_message_appreciation_flg'],
3049                    'card_company' => $this->sharedUserData['User']['card_company'],
3050                    'usersPointDetail' => $fetchAppreciationData['user_purchase_coin'] //NJ-12246: Get usersPointData
3051                );
3052
3053                //- NJ-23781 : get individual card flg if corporate users (card and bank transfer)
3054                if(in_array($userData->getMembershipTypeIndex(), Configure::read('corp_personal_card_payment_valid_memberships'))){
3055                    $getICFFlg = $this->UsersDetail->getCorpIndividualCardFlg(['user_id' => $this->Auth->user('id')]);
3056                    if($getICFFlg){
3057                        $appreciation_selection_modal_params['corp_individual_card_fail_flg'] = $getICFFlg['individual_card_fail_flg'];
3058                    }
3059                }
3060                if (
3061                    isset($fetchAppreciationData['user_message_appreciation_flg']) && $fetchAppreciationData['user_message_appreciation_flg'] == 1
3062                    ||
3063                    $finalTipShow == 1
3064                ){
3065                    $result['html_element'] = $view->element('appreciation_selection_modal', $appreciation_selection_modal_params);
3066                }
3067            }
3068
3069        }
3070        return $result;
3071    }
3072    /**
3073    * Send teacher's appreciation
3074    * @param : array( 'appreciation_id' => int, 'message' => str, 'chat_hash' => str )
3075    * @return : bool
3076    */
3077    public function sendTeacherAppreciation( $params = array() ) {
3078        $result = array( 'result' => 0 ); // false 
3079        $appreciationId = isset( $params['appreciation_id'] ) ? $params['appreciation_id'] : null; 
3080        $tipCoin = isset( $params['tip_coin'] ) ? $params['tip_coin'] : null;
3081        $message = isset( $params['message'] ) && $params['message'] ? $params['message'] : null; 
3082        $chathash = isset( $params['chat_hash'] ) && $params['chat_hash'] ? $params['chat_hash'] : null; 
3083        $action_mode = isset( $params['action_mode'] ) ? $params['action_mode'] : 0; 
3084
3085        $userData = $this->sharedUserData;
3086        $userID = $userData['User']['id'];
3087
3088        //fetch the show appreciation flg;show_appreciation_flg
3089        $userData = $this->User->find("first",array(
3090            'fields' => array(
3091                "User.show_appreciation_flg",
3092                "User.display_appreciation_message_flg"
3093            ),
3094            'conditions' => array(
3095                'User.id' => $userID
3096            )
3097        ));
3098
3099        $userData = $userData['User'] ?? array();
3100        $showAppreciationFlg = $userData['show_appreciation_flg'] ?? 0;
3101
3102        $showAppreciationMessageFlg = $userData['display_appreciation_message_flg'] ?? 0;
3103
3104        $sendParam = array(
3105            'chat_hash'  => $chathash,
3106            'appreciation_id'  => $appreciationId,
3107            'tip_coin'  => $tipCoin,
3108            'message' => $message,
3109            'access_point' => 'pc',
3110            'action_mode' => $action_mode
3111        );
3112
3113        //send the appreciation to teacher if flag is 1 
3114        if ((int)$showAppreciationFlg == 1 || (int)$showAppreciationMessageFlg == 1) {
3115            $sendData = $this->LessonOnairsLog->sendAppreciationToTeacher($sendParam);
3116            if ( isset ($sendData['result'] ) && $sendData['result'] ) {
3117                // set default res
3118                $result = array( 'result' => 1 );
3119
3120                // set return appreciation item
3121                $result['appreciation_details'] = $sendData['appreciation_item'];
3122
3123            } else {
3124                if( isset ($sendData['error'] ) && $sendData['error'] ){
3125                    $result['error']['id'] = 'sending_failed';
3126                    $result['error']['message'] = json_encode($sendData['error']);
3127                }
3128            }
3129        }else{
3130            $result['error']['id'] = 'show_flag_invalid';
3131            $result['error']['message'] = "Appreciation Show Flag is invalid, flag must be set to 'On' on the account settings";
3132        }
3133
3134        return $result;
3135    }
3136
3137    public function isLocalizeDirValid($code) {
3138
3139        $this->CountryCode->openDBReplica();
3140
3141        $result = $this->CountryCode->find('count', array(
3142            'conditions' => array('CountryCode.iso_639_1' => $code),
3143            'recursive' => -1
3144        ));
3145
3146        $this->CountryCode->closeDBReplica();
3147
3148        return $result;
3149    }
3150
3151    /**
3152    * Settle aftee payment receivables
3153    * @param array user data
3154    * @return boolean
3155    */
3156    protected function chargeAfteePaymentReceivable($params = array()) {
3157        //validate need data for payment receivable
3158        if (
3159            empty($params['id']) ||
3160            empty($params['email']) ||
3161            empty($params['currency_code']) ||
3162            empty($params['payment_plan_id']) ||
3163            empty($params['price_id']) ||
3164            empty($params['card_company'])
3165        )
3166        {
3167            $this->log(__METHOD__ . "error data pass. Data : " . json_encode($params), 'debug');
3168            return false;
3169        }
3170
3171        $userId = $params['id'];
3172        $currencyCode = $params['currency_code'];
3173        $paymentPlanId = $params['payment_plan_id'];
3174        $priceId = $params['price_id'];
3175
3176        // set db connection
3177        $db = ConnectionManager::getDataSource('default');
3178        //db resources reconnect
3179        if ($db->isConnected()) {
3180            $db->close(); // stop
3181        }
3182        $db->reconnect();
3183
3184        $rawQuery = "SELECT 
3185                (SELECT 
3186                        SUM(`amount`) AS `amount`
3187                    FROM
3188                        `payment_receivables`
3189                    WHERE
3190                        `payment_receivables`.`user_id` = u.id
3191                            AND `payment_receivables`.`status` = 0
3192                            AND `payment_receivables`.`payment_element_type` = 1
3193                            AND `payment_receivables`.`created` <= NOW()) AS receivables,
3194                (SELECT 
3195                        SUM(`amount`) AS `amount`
3196                    FROM
3197                        `payment_receivables`
3198                    WHERE
3199                        `payment_receivables`.`user_id` = u.id
3200                            AND `payment_receivables`.`status` = 0
3201                            AND `payment_receivables`.`payment_element_type` = 2
3202                            AND `payment_receivables`.`created` <= NOW()) AS appreciation_receivables,
3203                (SELECT 
3204                        SUM(`amount`) AS `amount`
3205                    FROM
3206                        `payment_receivables`
3207                    WHERE
3208                        `payment_receivables`.`user_id` = u.id
3209                            AND `payment_receivables`.`status` = 0
3210                            AND `payment_receivables`.`payment_element_type` = 3
3211                            AND `payment_receivables`.`created` <= NOW()) AS live_receivables                        
3212            FROM  users AS u WHERE u.id = {$userId}
3213        ";
3214
3215        $result = $this->User->query($rawQuery);
3216
3217        $receivableAmount = isset( $result[0][0]['receivables'] ) && $result[0][0]['receivables'] ? $result[0][0]['receivables'] : 0 ;
3218        $appreciationReceivableAmount = isset( $result[0][0]['appreciation_receivables'] ) && $result[0][0]['appreciation_receivables'] ? $result[0][0]['appreciation_receivables'] : 0 ;
3219        $liveReceivableAmount = isset( $result[0][0]['live_receivables'] ) && $result[0][0]['live_receivables'] ? $result[0][0]['live_receivables'] : 0 ;
3220        $totalReceivableAmount = $receivableAmount + $appreciationReceivableAmount + $liveReceivableAmount;
3221
3222        // check payment receivable
3223        if ( $totalReceivableAmount < 1 ) {
3224            $this->log(__METHOD__ . "::No payment receivable. \n Data : " . json_encode($params), 'debug');
3225            return false;
3226        }
3227
3228        //generate ordd code
3229        $paymentHash = myTools::generateOrderCode($userId);
3230        $membershipStatusIndex = UserTable::getStudentMembershipStatus($userId);
3231        // Reservation payment transaction 
3232        if( $receivableAmount > 0 ) {
3233
3234            $paymentParams = array(
3235                'currencyCode' => $currencyCode,
3236                'formType' => Configure::read('payment_credit_receivable'),
3237                'paymentType' => Configure::read('payment_types.payment_receivable'),
3238                'logFileName' => 'debug',
3239                'paymentAmount' => $receivableAmount,
3240                'priceId' => $priceId,
3241                'paymentPlanId' => $paymentPlanId
3242            );
3243
3244            $ptParams = array(
3245                'user_id' => $userId,
3246                'payment_hash' => $paymentHash,
3247                'course_id' => Configure::read("credit.course_id"),
3248                'payment_params' => json_encode($paymentParams),
3249            );
3250
3251            // create payment transaction
3252            if (!$pt = $this->PaymentTransaction->setWPPaymentTransaction($ptParams)) {
3253                $this->log(__METHOD__ . "::Cannot create payment transaction. \nData:" .json_encode($ptParams), 'debug');
3254                return false;
3255            }
3256            
3257        }
3258        // Appreciation payment transaction
3259        if( $appreciationReceivableAmount > 0 ) {
3260
3261            $paymentParams = array(
3262                'currencyCode' => $currencyCode,
3263                'formType' => Configure::read('payment_credit_appreciation_receivable'),
3264                'paymentType' => Configure::read('payment_types.payment_receivable'),
3265                'logFileName' => 'debug',
3266                'paymentAmount' => $appreciationReceivableAmount,
3267                'priceId' => $priceId,
3268                'paymentPlanId' => $paymentPlanId
3269            );
3270
3271            $ptParams = array(
3272                'user_id' => $userId,
3273                'payment_hash' => $paymentHash,
3274                'course_id' => Configure::read("credit.course_id"),
3275                'payment_params' => json_encode($paymentParams),
3276            );
3277
3278            // create payment transaction
3279            if (!$apt = $this->PaymentTransaction->setWPPaymentTransaction($ptParams)) {
3280                $this->log(__METHOD__ . "::Cannot create payment transaction. \nData:" .json_encode($ptParams), 'debug');
3281                return false;
3282            }
3283
3284        }
3285
3286        // Live payment transaction
3287        if ($liveReceivableAmount > 0) {
3288
3289            $paymentParams = array(
3290                'currencyCode' => $currencyCode,
3291                'formType' => Configure::read('payment_live_lesson_receivable'),
3292                'paymentType' => Configure::read('payment_types.payment_receivable'),
3293                'logFileName' => 'debug',
3294                'paymentAmount' => $liveReceivableAmount,
3295                'priceId' => $priceId,
3296                'paymentPlanId' => $paymentPlanId
3297            );
3298
3299            $ptParams = array(
3300                'user_id' => $userId,
3301                'payment_hash' => $paymentHash,
3302                'course_id' => Configure::read("credit.course_id"),
3303                'payment_params' => json_encode($paymentParams),
3304            );
3305
3306            // create payment transaction
3307            if (!$lpt = $this->PaymentTransaction->setWPPaymentTransaction($ptParams)) {
3308                $this->log(__METHOD__ . "::Cannot create payment transaction. \nData:" .json_encode($ptParams), 'debug');
3309                return false;
3310            }
3311        }
3312
3313        //db resources reconnect
3314        if ($db->isConnected()) {
3315            $db->close(); // stop
3316        }
3317        $db->reconnect();
3318
3319        // load PayPal class
3320        if (!class_exists('AfteePaymentService')) {
3321            App::import('Lib', 'AfteePaymentService');
3322        }
3323
3324        $afteeChecksumData = array(
3325            'shopItemId' => "AFTEE" . Configure::read('payment_credit_receivable'),
3326            'itemName' => 'PaymentReceivables',
3327            'itemPrice' => (int)$totalReceivableAmount,
3328            'itemCount' => 1,
3329            'customerPhoneNumber' => $params['phone_number'],
3330            'customerEmail' => $params['email'],
3331            'shopTransactionNo' => $paymentHash,
3332            'userID' => $userId
3333        );
3334        $afteeService = new AfteePaymentService();
3335        $checksum = $afteeService->generateChecksum($afteeChecksumData, false);
3336        
3337
3338        $afteeData = array(
3339            'authentication_token' => $params['card_token'],
3340            'related_id' => $params['aftee_transaction_identifier'],
3341            'checksum' => $checksum['checksum'],
3342            'shop_transaction_no' => $paymentHash,
3343            'transaction_options' => array(1)
3344        );
3345
3346        $afteePaymentData = array_merge($afteeData, $checksum['settlementData']);
3347
3348        // process Aftee direct payment
3349        $res = $afteeService->directPayment($afteePaymentData);
3350        $checkRes = json_decode($res, true);
3351        $orderResult = $res;
3352
3353        if ( isset($checkRes['object']) && $checkRes['object'] == 'transaction') {
3354            $paymentSuccess = true;
3355        } else if ( !array_key_exists("object", $checkRes) || (isset($checkRes['object']) && $checkRes['object'] == 'error')) {
3356            $paymentSuccess = false;
3357        }
3358
3359        $this->loadModel('Payment');
3360
3361        // Reservation payment
3362        if( $receivableAmount > 0 ) {
3363            $savePaymentArr = array(
3364                'user_id' => $userId,
3365                'type_id' => 2,
3366                'pay_kbn' => 1,
3367                'reference_id' => $userId,
3368                'payment_transaction_password' => $paymentSuccess ? $pt['password'] : '',
3369                'status' => $paymentSuccess ? 1 : '',
3370                'form_type' => Configure::read('payment_credit_receivable'),
3371                'ordd' => $paymentSuccess ? $paymentHash : '',
3372                'amount' => $receivableAmount,
3373                'param1' => $res,
3374                'param2' => $paymentSuccess ? '' : 'error',
3375                'card_company' => Configure::read('card_company.aftee'),
3376                'transaction_code' => $paymentSuccess ? $paymentHash : '',
3377                'currency_id' => Configure::read('default.settlement_currency_id'),
3378                'currency_code' => $currencyCode,
3379                'payment_id' => $paymentPlanId,
3380                'price_id' => $priceId,
3381                'payment_type' => Configure::read('payment_types.payment_receivable'),
3382                'logFileName' => 'debug'
3383            );
3384
3385            // create new payment
3386            $paymentSave = $this->Payment->rawSavePayment($savePaymentArr);
3387        }
3388
3389        // Appreciation payment
3390        if( $appreciationReceivableAmount > 0 ) {
3391            $savePaymentArr = array(
3392                'user_id' => $userId,
3393                'type_id' => 2,
3394                'pay_kbn' => 1,
3395                'reference_id' => $userId,
3396                'payment_transaction_password' => $paymentSuccess ? $pt['password'] : '',
3397                'status' => $paymentSuccess ? 1 : '',
3398                'form_type' => Configure::read('payment_credit_appreciation_receivable'),
3399                'ordd' => $paymentSuccess ? $paymentHash : '',
3400                'amount' => $appreciationReceivableAmount,
3401                'param1' => $res,
3402                'param2' => $paymentSuccess ? '' : 'error',
3403                'card_company' => Configure::read('card_company.aftee'),
3404                'transaction_code' => $paymentSuccess ? $paymentHash : '',
3405                'currency_id' => Configure::read('default.settlement_currency_id'),
3406                'currency_code' => $currencyCode,
3407                'payment_id' => $paymentPlanId,
3408                'price_id' => $priceId,
3409                'payment_type' => Configure::read('payment_types.payment_receivable'),
3410                'logFileName' => 'debug'
3411            );
3412
3413            // create new payment
3414            $paymentSave = $this->Payment->rawSavePayment($savePaymentArr);
3415        }
3416
3417        // Live payment
3418        if( $liveReceivableAmount > 0 ) {
3419            $savePaymentArr = array(
3420                'user_id' => $userId,
3421                'type_id' => 2,
3422                'pay_kbn' => 1,
3423                'reference_id' => $userId,
3424                'payment_transaction_password' => $paymentSuccess ? $pt['password'] : '',
3425                'status' => $paymentSuccess ? 1 : '',
3426                'form_type' => Configure::read('payment_live_lesson_receivable'),
3427                'ordd' => $paymentSuccess ? $paymentHash : '',
3428                'amount' => $liveReceivableAmount,
3429                'param1' => $res,
3430                'param2' => $paymentSuccess ? '' : 'error',
3431                'card_company' => Configure::read('card_company.aftee'),
3432                'transaction_code' => $paymentSuccess ? $paymentHash : '',
3433                'currency_id' => Configure::read('default.settlement_currency_id'),
3434                'currency_code' => $currencyCode,
3435                'payment_id' => $paymentPlanId,
3436                'price_id' => $priceId,
3437                'payment_type' => Configure::read('payment_types.payment_receivable'),
3438                'logFileName' => 'debug'
3439            );
3440
3441            // create new payment
3442            $paymentSave = $this->Payment->rawSavePayment($savePaymentArr);
3443        }        
3444
3445        if ($paymentSave && $paymentSuccess) {
3446
3447            // Update Reservation payment receivables
3448            if( $receivableAmount > 0 ) {
3449                // get payment id
3450                $paymentData = $this->Payment->find('first', array(
3451                    'fields' => array(),
3452                    'conditions' => array(
3453                        'user_id' => $userId,
3454                        'form_type' => Configure::read('payment_credit_receivable'),
3455                        'ordd' => $paymentHash
3456                    ),
3457                    'recursive' => -1
3458                ));
3459
3460                if ($paymentData) {
3461                    $this->loadModel('PaymentReceivable');
3462                    // set payment receivable statuses to 2 - received
3463                    $this->PaymentReceivable->updateReceivableReservationPayment(
3464                        $userId,
3465                        array(
3466                            'status' => 2,
3467                            'payment_id' => $paymentData['Payment']['id'],
3468                            'payment_collection_date' => date("Y-m-d H:i:s"),
3469                            'card_company' => Configure::read('card_company.aftee'),
3470                            'payment_plan_id' => $paymentPlanId,
3471                            'membership_type_index' => $membershipStatusIndex
3472                        ),
3473                        array(
3474                            'PaymentReceivable.user_id' => $userId,
3475                            'PaymentReceivable.status' => 0,
3476                            'PaymentReceivable.payment_element_type' => 1,
3477                            'PaymentReceivable.created <=' => date('Y-m-d H:i:s')
3478                        )
3479                    );
3480                }
3481            }
3482
3483            // Update Appreciation payment receivables
3484            if( $appreciationReceivableAmount > 0 ) {
3485                // get payment id
3486                $paymentData = $this->Payment->find('first', array(
3487                    'fields' => array(),
3488                    'conditions' => array(
3489                        'user_id' => $userId,
3490                        'form_type' => Configure::read('payment_credit_appreciation_receivable'),
3491                        'ordd' => $paymentHash
3492                    ),
3493                    'recursive' => -1
3494                ));
3495
3496                if ($paymentData) {
3497                    $this->loadModel('PaymentReceivable');
3498                    // set payment receivable statuses to 2 - received
3499                    $this->PaymentReceivable->updateReceivableReservationPayment(
3500                        $userId,
3501                        array(
3502                            'status' => 2,
3503                            'payment_id' => $paymentData['Payment']['id'],
3504                            'payment_collection_date' => date("Y-m-d H:i:s"),
3505                            'card_company' => Configure::read('card_company.aftee'),
3506                            'payment_plan_id' => $paymentPlanId,
3507                            'membership_type_index' => $membershipStatusIndex
3508                        ),
3509                        array(
3510                            'PaymentReceivable.user_id' => $userId,
3511                            'PaymentReceivable.status' => 0,
3512                            'PaymentReceivable.payment_element_type' => Configure::read('appreciation_data.payment_element_type'),
3513                            'PaymentReceivable.created <=' => date('Y-m-d H:i:s')
3514                        )
3515                    );
3516                }
3517            }
3518
3519            // Update live payment receivables
3520            if( $liveReceivableAmount > 0 ) {
3521                // get payment id
3522                $paymentData = $this->Payment->find('first', array(
3523                    'fields' => array(),
3524                    'conditions' => array(
3525                        'user_id' => $userId,
3526                        'form_type' => Configure::read('payment_live_lesson_receivable'),
3527                        'ordd' => $paymentHash
3528                    ),
3529                    'recursive' => -1
3530                ));
3531
3532                if ($paymentData) {
3533                    $this->loadModel('PaymentReceivable');
3534                    // set payment receivable statuses to 2 - received
3535                    $this->PaymentReceivable->updateReceivableReservationPayment(
3536                        $userId,
3537                        array(
3538                            'status' => 2,
3539                            'payment_id' => $paymentData['Payment']['id'],
3540                            'payment_collection_date' => date("Y-m-d H:i:s"),
3541                            'card_company' => Configure::read('card_company.aftee'),
3542                            'payment_plan_id' => $paymentPlanId,
3543                            'membership_type_index' => $membershipStatusIndex                            
3544                        ),
3545                        array(
3546                            'PaymentReceivable.user_id' => $userId,
3547                            'PaymentReceivable.status' => 0,
3548                            'PaymentReceivable.payment_element_type' => 3,
3549                            'PaymentReceivable.created <=' => date('Y-m-d H:i:s')
3550                        )
3551                    );
3552                }
3553            }            
3554
3555        }
3556        if( isset($pt['id']) ) {
3557            $ptUpdateParams = array(
3558                'id' => $pt['id'],
3559                'fields' => array(
3560                    'status' => $paymentSuccess ? 1 : 2,
3561                    'response_text' => array('aftee_directPayment_response' => $orderResult)
3562                ),
3563                'logFileName' => 'debug'
3564            );
3565
3566            // update payment transaction
3567            if (!$this->PaymentTransaction->updateAfteePaymentTransaction($ptUpdateParams)) {
3568                $this->log(__METHOD__ . ' Cannot update payment transaction. --> ' . json_encode($ptUpdateParams), 'debug');
3569            }
3570        }
3571
3572        if( isset($apt['id']) ) {
3573            $ptUpdateParams = array(
3574                'id' => $apt['id'],
3575                'fields' => array(
3576                    'status' => $paymentSuccess ? 1 : 2,
3577                    'response_text' => array('aftee_directPayment_response' => $orderResult)
3578                ),
3579                'logFileName' => 'debug'
3580            );
3581            // update payment transaction
3582            if (!$this->PaymentTransaction->updateAfteePaymentTransaction($ptUpdateParams)) {
3583                $this->log(__METHOD__ . ' Cannot update payment transaction. --> ' . json_encode($ptUpdateParams), 'debug');
3584            }
3585        }
3586
3587        if( isset($lpt['id']) ) {
3588            $ptUpdateParams = array(
3589                'id' => $lpt['id'],
3590                'fields' => array(
3591                    'status' => $paymentSuccess ? 1 : 2,
3592                    'response_text' => array('aftee_directPayment_response' => $orderResult)
3593                ),
3594                'logFileName' => 'debug'
3595            );
3596            // update payment transaction
3597            if (!$this->PaymentTransaction->updateAfteePaymentTransaction($ptUpdateParams)) {
3598                $this->log(__METHOD__ . ' Cannot update payment transaction. --> ' . json_encode($ptUpdateParams), 'debug');
3599            }
3600        }        
3601
3602        // log
3603        $this->log(__METHOD__ . "::PaymentReceivable charge on withdrawal. \nData: " . json_encode(array('params' => $params, 'result' => $orderResult)), 'debug');
3604    }
3605
3606    /**
3607     * Aftee Payment method
3608     * Check if aftee should be enabled/disabled in app
3609     */
3610    public function checkAfteeSupported($userData,$pcFlag = false) {
3611        $afteeAppSupportedVersion = Configure::read('aftee_app_version_support');
3612        $appVersion = isset($this->request->query['appVersion']) && !empty($this->request->query['appVersion']) ? $this->request->query['appVersion'] : 0;
3613        $deviceType = isset($this->request->query['deviceType']) && !empty($this->request->query['deviceType']) ? $this->request->query['deviceType'] : 0;
3614
3615        // initial values
3616        $isAfteeUser = isset($this->isAfteeUser) ? $this->isAfteeUser : 0;
3617        $enableAftee = (isset($userData['currency_code']) && $userData['currency_code'] == 'TWD') ? 1: 0;
3618
3619
3620        if (!$pcFlag) {
3621            // validate
3622            if (
3623                (isset($this->localizeIPLang) && !empty($this->localizeIPLang) && $this->localizeIPLang != 'TWD') // allow taiwan IP only
3624                || ($deviceType == "1" && version_compare($appVersion, $afteeAppSupportedVersion[$deviceType], '<')) // check ios app supported version
3625                || (in_array($deviceType, array(2,3)) && version_compare($appVersion, $afteeAppSupportedVersion[$deviceType], '<')) // check android|amazon app supported version
3626            ) {
3627                $enableAftee = 0;
3628                $isAfteeUser = 0;
3629            }
3630        }else{
3631            
3632            // - validate if PC
3633            if (
3634                $appVersion == 0 && 
3635                $deviceType == 0 && 
3636                $this->localizeDir != "zh-tw" 
3637                || 
3638                ($userData['currency_code'] == 'TWD' && $this->localizeDir != "zh-tw" )
3639                ||
3640                ($userData['currency_code'] != 'TWD' && $this->localizeDir != "zh-tw" )
3641                ||
3642                ($userData['currency_code'] != 'TWD' && $this->localizeDir == "zh-tw" )
3643            ) { 
3644                $enableAftee = 0;
3645                $isAfteeUser = 0;
3646            }
3647        }
3648
3649
3650        // set final values
3651        $this->set('isAfteeUser', false);
3652        $this->set('enableAftee', false);
3653    }
3654
3655    public function queryGuideControl()
3656    {
3657        $this->GuideNavigationbarCategory->openDBReplica();
3658        $datas = $this->GuideNavigationbarCategory->find('all', array(
3659            'fields' => array(
3660                'GuideNavigationbarCategory.id',
3661                'GuideNavigationbarCategory.category_name',
3662                'GuideNavigationbarCategory.lang',
3663                'GuideNavigationbarCategory.display_order',
3664                'GuideNavigationbarContent.id',
3665                'GuideNavigationbarContent.content_name',
3666                'GuideNavigationbarContent.url',
3667                'GuideNavigationbarContent.display_order',
3668                'GuideNavigationbarContent.crawl_flg',
3669                '(SELECT GROUP_CONCAT(DISTINCT (unloggedin_flg)) FROM guide_navigationbar_auth_control WHERE guide_navigationbar_content_id = GuideNavigationbarContent.id) as unloggedin_flg',
3670                '(SELECT GROUP_CONCAT(DISTINCT (membership_type)) FROM guide_navigationbar_membership_control WHERE guide_navigationbar_content_id = GuideNavigationbarContent.id) as membership_type',
3671                '(SELECT GROUP_CONCAT(DISTINCT (currency_code)) FROM guide_navigationbar_currency_control WHERE guide_navigationbar_content_id = GuideNavigationbarContent.id) as currency_code',
3672                '(SELECT GROUP_CONCAT(DISTINCT (browser_language)) FROM guide_navigationbar_browser_lang_control WHERE guide_navigationbar_content_id = GuideNavigationbarContent.id) as browser_language'
3673            ),
3674            'joins' => array(
3675                array(
3676                    'type' => 'LEFT',
3677                    'table' => 'guide_navigationbar_content',
3678                    'alias' => 'GuideNavigationbarContent',
3679                    'conditions' => 'GuideNavigationbarCategory.id = GuideNavigationbarContent.category_id'
3680                )
3681            ),
3682            'conditions' => array(
3683                'GuideNavigationbarCategory.device_type' => 1,
3684                'GuideNavigationbarContent.device_type' => 1
3685            ),
3686            'group' => 'GuideNavigationbarContent.id',
3687            'order' => array(
3688                'GuideNavigationbarCategory.display_order ASC',
3689                'GuideNavigationbarContent.display_order ASC'
3690            ),
3691            'recursive' => -1
3692        ));
3693        $this->GuideNavigationbarCategory->closeDBReplica();
3694
3695        $guideControlCat = array();
3696        if ($datas) {
3697            foreach ($datas as $key=>$data) {
3698                $category_id = $data['GuideNavigationbarCategory']['id'];
3699                $category_name = $data['GuideNavigationbarCategory']['category_name'];
3700
3701                $guideControlCat[$category_id]['category_name'] = $category_name;
3702                $guideControlCat[$category_id]['guide_navigation_bar_content'][$key]['content'] = $data['GuideNavigationbarContent'];
3703                $guideControlCat[$category_id]['guide_navigation_bar_content'][$key]['control'] = $data['0'];
3704            }
3705
3706            $redis = new myRedis();
3707            $redisKey = "dynamic_global_guide_control";
3708
3709            $guideControlCached = $redis->get($redisKey);
3710
3711            if (!$guideControlCached){
3712                $redis->set(array(
3713                    'key' => $redisKey,
3714                    'value' => json_encode($guideControlCat)
3715                ));
3716            }
3717        }
3718
3719        $this->set('GuideNavigationbarCategory', $guideControlCat);
3720    }
3721
3722    // 
3723    public function queryLineHoverControl(){
3724
3725        $returnData = array();
3726
3727        $this->RyugakuSchoolLineSetting->openDBReplica();
3728        $datas = $this->RyugakuSchoolLineSetting->find('all',array(
3729            'fields' => array(
3730                'RyugakuSchoolLineSetting.id',
3731                'RyugakuSchoolLineSetting.line_title',
3732                'RyugakuSchoolLineSetting.line_description',
3733                'RyugakuSchoolLineSetting.line_hover_location_url'
3734            ),
3735            'conditions' => array(),
3736            'recursive' => -1
3737        ));
3738        $this->RyugakuSchoolLineSetting->closeDBReplica();
3739
3740        if ($datas) {
3741            foreach ($datas as $key => $hover) {
3742
3743                $hover=$hover['RyugakuSchoolLineSetting'];
3744
3745                $returnData[] = array(
3746                    'title' => $hover['line_title'],
3747                    'description' => $hover['line_description'],
3748                    'url' => $hover['line_hover_location_url']
3749                );
3750            }
3751        }
3752
3753        $this->set('lineHoverGuide', $returnData);
3754    }
3755
3756    /**
3757     * NJ-27594
3758     * @param String $version - app version,
3759     * @param Int $device_type - 1 - iOS, 2 Android
3760     *
3761     * @return void
3762     */
3763    private function NCPlusPositionUrlScheme($version, $device_type) {
3764        $supportedVersion = Configure::read('nc_plus_positions_url_scheme')[$device_type];
3765        if( version_compare($version, $supportedVersion, '>=')) {
3766            $this->set('position_url_scheme_support', 1);    
3767        } 
3768    }
3769
3770    // NJ-18780 : light plan 
3771    public function checkLitePlanSupported($userData = array(),$pcFlag = false,$page = null){
3772        $enableLitePlan = 0;
3773        $isLitePlanUser = 0;
3774            
3775        $litePlanAppSupportedVersion = Configure::read('lite_plan_app_version_support');
3776        $appVersion = isset($this->request->query['appVersion']) && !empty($this->request->query['appVersion']) ? $this->request->query['appVersion'] : 0;
3777        $deviceType = isset($this->request->query['deviceType']) && !empty($this->request->query['deviceType']) ? $this->request->query['deviceType'] : 0;
3778    
3779        if ($userData) {
3780                // added localize dir overriding to properly get the lite plan data even if the user account is in different language site but currency code is JPY.
3781                $localizeDir = (isset($userData['override_localize_dir'])) ? $userData['override_localize_dir'] : $this->localizeDir;
3782                $setEnableLitePlan = UserTable::checkLitePlanSupported($userData,$pcFlag,$appVersion,$deviceType,$localizeDir,$this->localizeIPLang);
3783    
3784                $enableLitePlan = $setEnableLitePlan['enableLitePlan'];
3785                $isLitePlanUser = $setEnableLitePlan['isLitePlanUser'];
3786    
3787                // - prem complimentary that wan't to change to plan using credit_charge
3788                if (
3789                    isset($userData['payment_plan_id']) && 
3790                    $userData['payment_plan_id'] &&
3791                    $userData['payment_plan_id'] == Configure::read('payment_plans.complimentary_plan') &&
3792                    isset($userData['complimentary_code']) &&
3793                    $userData['complimentary_code'] &&
3794                    in_array($page, array('credit_charge'))
3795                ) {
3796                    # allow check enable lite plan
3797                    if ($this->localizeDir == 'ja') {
3798                        $enableLitePlan = (isset($userData['currency_code']) && $userData['currency_code'] == 'JPY') ? 1: 0;
3799                    } else {
3800                        $enableLitePlan = 0;
3801                    }
3802                }
3803    
3804                if (!empty($page) && !in_array($page, array('credit_charge'))) { 
3805                    $enableLitePlan = 0;
3806                    $isLitePlanUser = 0;
3807
3808                    if ($this->localizeDir == 'ja') {
3809                        $enableLitePlan = 1;
3810                    }
3811                }
3812                
3813                // - allow for corporate charge page 
3814                if (
3815                    isset($userData['corporate_id']) && 
3816                    $userData['corporate_id'] && 
3817                    isset($userData['payment_plan_id']) && 
3818                    $userData['payment_plan_id'] && 
3819                    in_array($page, array('credit_charge'))                    
3820                ) {
3821                    # allow check enable lite plan
3822                    if ($this->localizeDir == 'ja') {
3823                        $enableLitePlan = (isset($userData['currency_code']) && $userData['currency_code'] == 'JPY') ? 1: 0;
3824                    } else {
3825                        $enableLitePlan = 0;
3826                    }
3827                }
3828        }
3829    
3830        // set final values
3831        $this->set('enableLitePlan',$enableLitePlan);
3832        $this->set('isLitePlanUser',$isLitePlanUser);
3833    
3834        // - set return to view 
3835        return array('enableLitePlan' => $enableLitePlan,'isLitePlanUser' => $isLitePlanUser);
3836    
3837    }
3838
3839    /**
3840     * NJ-27262: Resets Users Preset when 
3841     * changed to Chocotto Camp
3842     */
3843    public function resetPresetTextbook($params = []) {
3844        $this->autoRender = false;
3845        $this->layout = false;
3846
3847        if(!$params) {
3848            return;
3849        }
3850
3851        $connect_id = isset($params['connect_id']) ? $params['connect_id'] : Configure::read('textbook_default.chocotto_textbook_connect_id');
3852        
3853        myTools::initializeApiTunnel(array('TextbookUpdatePresetController'));
3854        
3855        $preset = new TextbookUpdatePresetController();
3856
3857        $user = $this->User->find('first', array(
3858            'fields' => array(
3859                'User.id',
3860                'User.api_token',
3861            ),
3862            'conditions' => array(
3863                'User.id' => $params['user_id']
3864            )
3865        ));
3866        
3867        if($user) {
3868            $apiParams = array(
3869                'connect_id' => $connect_id,
3870                'users_api_token' => $user['User']['api_token'],
3871                'nc_terminal_type' => Configure::read('nc_terminal_type.pc')
3872            );
3873    
3874            $preset->params = $apiParams;
3875            $preset->index();
3876        }
3877        
3878    }
3879    
3880    public function setPaypalUser($user = array()) {
3881        
3882        // Check if paypal user
3883        $isPaypalUser = (isset($user['paypal_payer_id']) && isset($user['paypal_payer_email']) && $user['paypal_payer_email']) ? true : false;
3884        $paypal_icon = "/images/pay/Icon_paypal.png";
3885        $paypal_payer_email = (isset($user['paypal_payer_email']) && $user['paypal_payer_email']) ? $user['paypal_payer_email'] : null;
3886
3887        $this->set('isPaypalUser', $isPaypalUser);
3888        $this->set('paypal_icon', $paypal_icon);
3889        $this->set('paypal_payer_email', $paypal_payer_email);
3890    }
3891
3892
3893    /**
3894     * Stripe Payment method
3895     * Check if stripe apple/google pay should be enabled/disabled in app
3896     */
3897    public function checkStripeSupported($userData,$pcFlag = false) {
3898        $stripeAppSupportedVersion = Configure::read('stripe_app_version_support');
3899        $stripeAppSupportedCurrencies = Configure::read('stripe.allowed_currencies');
3900        $appVersion = isset($this->request->query['appVersion']) && !empty($this->request->query['appVersion']) ? $this->request->query['appVersion'] : 0;
3901        $deviceType = isset($this->request->query['deviceType']) && !empty($this->request->query['deviceType']) ? $this->request->query['deviceType'] : 0;
3902        $device = myTools::getDevice();
3903        $userCurrecy = isset($userData['currency_code']) ? $userData['currency_code'] : '';
3904        if(isset($this->mobAppUserData) && $this->mobAppUserData['User']['currency_code']) {
3905            $userCurrecy = $this->mobAppUserData['User']['currency_code'];
3906        } else {
3907            $userCurrecy = isset($this->sharedUserData) && is_array($this->sharedUserData) && $this->sharedUserData['User']['currency_code'] ? $this->sharedUserData['User']['currency_code'] : Configure::read('default.user_currency');
3908        }
3909
3910        // initial values
3911        $isStripeUser = isset($this->isStripeUser) ? $this->isStripeUser : false;
3912        $enableStripe = false;
3913        $stripePaymentType = $device == 3 ? 'apple' : 'google';
3914        $stripeChangePaymentMethod = false;
3915
3916        if (
3917            $isStripeUser ||
3918            (
3919                ($device == "3" && version_compare($appVersion, $stripeAppSupportedVersion[1], '>=') && in_array($userCurrecy, $stripeAppSupportedCurrencies['apple'])) // ios app supported version
3920                || (in_array($device, array(2,4)) && version_compare($appVersion, $stripeAppSupportedVersion[2], '>=') && in_array($userCurrecy, $stripeAppSupportedCurrencies['google'])) // android|amazon app supported version
3921            )
3922        ) {
3923            $enableStripe = true;
3924        }
3925
3926        // Phase 1: Disbale Stripe in some payment pages
3927        if (isset($this->request->params['action']) && !in_array($this->request->params['action'], array('credit', 'creditform', 'native_plan', 'wp_credit', 'wp_creditform', 'mobapp_credit_change_form', 'mobapp_wp_credit_change_form', 'mobapp_wp_credit_retry', 'mobapp_wp_credit_retry_form', 'mobapp_wp_credit_retry_confirm', 'mobapp_credit_retry', 'mobapp_credit_retry_form', 'mobapp_credit_retry_complete'))) {
3928            $enableStripe = false;
3929        }
3930
3931        // Change Payment method: enable for Stripe users only
3932        if (
3933            isset($this->request->params['action']) && in_array($this->request->params['action'], array('mobapp_credit_change_form', 'mobapp_wp_credit_change_form'))
3934        ) {
3935            $stripeChangePaymentMethod = true;
3936            if (!$isStripeUser) {
3937                $enableStripe = false;
3938            }
3939            
3940        }
3941
3942        // Failed Payment Retry: enable for Stripe users only
3943        if (
3944            (isset($this->request->params['action']) && in_array($this->request->params['action'], array('mobapp_wp_credit_retry', 'mobapp_wp_credit_retry_form', 'mobapp_wp_credit_retry_confirm', 'mobapp_credit_retry', 'mobapp_credit_retry_form', 'mobapp_credit_retry_complete')))
3945            && !$isStripeUser
3946        ) {
3947            $enableStripe = false;        
3948        }
3949
3950        // Disable Stripe if KRW and GPay
3951        if ($isStripeUser && $userCurrecy == 'KRW' && $stripePaymentType != 'apple') {
3952            $enableStripe = false;
3953        }
3954
3955        // set final values
3956        $this->set('isStripeUser', $isStripeUser);
3957        $this->set('enableStripe', $enableStripe);
3958        $this->set('stripePaymentType', $stripePaymentType);
3959        $this->set('stripeChangePaymentMethod', $stripeChangePaymentMethod);
3960    }
3961    /**
3962     * ~NJ-29078 - process child receivable payment 
3963     * @param array $familyArr, array $parentArr
3964     */
3965    public function processChildReceivablePayment($familyArr = [], $parentArr = [])
3966    {
3967        $logFileName = 'family_plan';
3968        $curlPayment = "";
3969
3970        if (!$pt = $this->Payment->setUpWithdrawTransaction($familyArr, $logFileName)) {
3971            return false;
3972        }
3973
3974        // ~if zero receivable just return success
3975        if (isset($pt['totalAmount']) && $pt['totalAmount'] == 0) {
3976            $this->log(__METHOD__ . ' No receivable to process' . json_encode($pt), $logFileName);
3977            $curlPayment = "success_order";
3978            return $curlPayment;
3979        }
3980
3981        $familyObj = new UserTable($familyArr);
3982        $parentObj = new UserTable($parentArr);
3983
3984        if ($parentObj->card_company == Configure::read('card_company.zeus')) {
3985            $data = array(
3986                'clientIp' => PaymentTable::getClientIpByCompanyId($parentObj->card_company),
3987                'email' => $parentObj->email,
3988                'sendId' => $parentObj->id,
3989                'money' => $pt['totalAmount'],
3990                'paymentHash' => $pt['payment_hash']
3991            );
3992            // ~process
3993            $curlPayment = $this->ZCharge->charge_with_regsterd_card(json_encode($data));
3994            $curlPayment = PaymentTable::checkPaymentResult($curlPayment);
3995        } else if ($parentObj->card_company == Configure::read('card_company.worldpay')) {
3996            $paymentMethodType = myTools::getWPPaymentMethodType($parentObj->card_brand, 'payment');
3997            $merchantCode = myTools::getWPMerchantCode($paymentMethodType);
3998            $paymentHash = $pt['payment_hash'];
3999            $paymentMethod = explode('_', $paymentMethodType);
4000            $paymentMethod = isset($paymentMethod[0]) ? $paymentMethod[0] : null;
4001            $currencyExponents = Configure::read('worldpay.currency_exponents');
4002            $exponent = $currencyExponents[$parentObj->currency_code];
4003            // get amount with checking currency exponent
4004            $amountArr = myTools::wpGetAmount($exponent, $pt['totalAmount']);
4005            $wpAmount = $amountArr['wpAmount'];
4006
4007            $decodePaymentParams = json_decode($pt['payment_params']);
4008            $paymentFormType = $decodePaymentParams->formType;
4009
4010            $wpParams = array(
4011                'merchantCode' => $merchantCode,
4012                'orderCode' => $paymentHash,
4013                'description' => 'Child Withdrawal Receivables',
4014                'currencyCode' => $parentObj->currency_code,
4015                'exponent' => $exponent,
4016                'amount' => $wpAmount,
4017                'cardToken' => $parentObj->card_token,
4018                'email' => $parentObj->email,
4019                'authenticatedShopperId' => $parentObj->id,
4020                'xmlName' => 'direct_payment_with_token',
4021                'shopperIpAddress' => $_SERVER["REMOTE_ADDR"],
4022                'wpTransactionIdentifier' => $parentObj->wp_transaction_identifier,
4023                'paymentMethod' => $paymentMethod
4024            );
4025
4026            $updateData = array(
4027                'id' => $pt['id'],
4028                'fields' => array('payment_params' => $wpParams)
4029            );
4030
4031            if (!$this->PaymentTransaction->updateWPPaymentTransaction($updateData)) {
4032                $this->log(__METHOD__ . ' Failed to update payment transaction' . json_encode($updateData), $logFileName);
4033            } else {
4034                if (!$pt = $this->PaymentTransaction->getWPPaymentTransaction($paymentHash)) {
4035                    return false;
4036                }
4037            }
4038
4039            // ~process
4040            $res = wpPaymentService::directPayment($wpParams);
4041
4042            $updateData = array(
4043                'id' => $pt['id'],
4044                'fields' => array('response_text' => array('directPayment_response' => $res))
4045            );
4046
4047            if (!$this->PaymentTransaction->updateWPPaymentTransaction($updateData)) {
4048                $this->log(__METHOD__ . ' Failed to update payment transaction' . json_encode($updateData), $logFileName);
4049            }
4050
4051            if (!myTools::checkIfWPPaymentResponseIsAuthorised($res)) {
4052                $curlPayment = "";
4053                $this->log(__METHOD__ . ' Not authorised payment worldpay' . (isset($familyObj->id) ? $familyObj->id : ''), $logFileName);
4054            } else {
4055                $curlPayment = "success_order";
4056            }
4057        } else if ($parentObj->card_company == Configure::read('card_company.aftee')) {
4058            $paymentMethodType = myTools::getWPPaymentMethodType($parentObj->card_brand, 'payment');
4059            $merchantCode = myTools::getWPMerchantCode($paymentMethodType);
4060            $paymentHash = $pt['payment_hash'];
4061            $paymentMethod = explode('_', $paymentMethodType);
4062            $paymentMethod = isset($paymentMethod[0]) ? $paymentMethod[0] : null;
4063            $decodePaymentParams = json_decode($pt['payment_params']);
4064            $paymentFormType = $decodePaymentParams->formType;
4065
4066            $afteeParams = array(
4067                'merchantCode' => $merchantCode,
4068                'orderCode' => $paymentHash,
4069                'description' => 'Family Plan Registration',
4070                'currencyCode' => $parentObj->currency_code,
4071                'amount' => $pt['totalAmount'],
4072                'cardToken' => $parentObj->card_token,
4073                'email' => $parentObj->email,
4074                'authenticatedShopperId' => $parentObj->id,
4075                'shopperIpAddress' => $_SERVER["REMOTE_ADDR"],
4076                'afteeTransactionIdentifier' => $parentObj->aftee_transaction_identifier,
4077                'paymentMethod' => $paymentMethod
4078            );
4079
4080            $updateData = array(
4081                'id' => $pt['id'],
4082                'fields' => array('payment_params' => $afteeParams)
4083            );
4084
4085            if (!$this->PaymentTransaction->updateAfteePaymentTransaction($updateData)) {
4086                $this->log(__METHOD__ . ' Failed to update payment transaction' . json_encode($updateData), $logFileName);
4087            } else {
4088                if (!$pt = $this->PaymentTransaction->getAfteePaymentTransaction($paymentHash)) {
4089                    return false;
4090                }
4091            }
4092
4093            // ~process
4094            $afteeParams = array(
4095                'parent' =>  $parentObj,
4096                'child' =>  $familyObj,
4097                'paymentTransaction' => $pt,
4098                'appreciationFlg' => $familyObj->allow_appreciation_flg,
4099                'tipAmount' => myTools::stringToFloat($familyObj->tip_max_amount)
4100            );
4101
4102            $curlPayment = $this->processChildAfteePayment($afteeParams);
4103        } elseif ($parentObj->card_company == Configure::read('card_company.paypal')) {
4104            $paypalParams = array(
4105                'parent' => $parentObj,
4106                'child' => $familyObj,
4107                'paymentTransaction' => $pt,
4108                'memberStatus' => 'exist'
4109            );
4110
4111            $curlPayment = $this->processChildPaypalPayment($paypalParams);
4112        } else if ($parentObj->card_company == Configure::read('card_company.stripe.apple') || $parentObj->card_company == Configure::read('card_company.stripe.google')){
4113            if (!class_exists('Stripe')) {
4114                App::import('Lib', 'Stripe');
4115            }
4116
4117            $data = array(
4118                'customerId' => $parentObj->stripe_customer_id,
4119                'amount' => $pt['totalAmount'],
4120                'currency' => $parentObj->currency_code,
4121                'paymentMethodID' => $parentObj->stripe_payment_identifier,
4122                'description' => 'Family Plan Receivable Payment',
4123                'sendpoint' => $pt['payment_hash'],
4124                'sendid' => $parentObj->id,
4125                'card_company' => $parentObj->card_company
4126            );
4127            
4128            $stripe = new Stripe();
4129            $curlPayment = $stripe->directPayment($data);    
4130            $curlPayment = myTools::checkStripePaymentResponse($curlPayment);
4131
4132        }
4133
4134        return $curlPayment;
4135    }
4136
4137    // ~NJ-29078 - Withdraw Paypal Process Payment
4138    private function processChildPaypalPayment($params = array())
4139    {
4140        $logFileName = 'family_plan';
4141        if (
4142            !isset($params['child']) ||
4143            !isset($params['parent']) ||
4144            !isset($params['paymentTransaction'])
4145        ) {
4146            $this->log('__METHOD__' . ' missing parameter(s). --> ' . json_encode($params), $logFileName);
4147            return false;
4148        }
4149
4150        // ~check for family parent 
4151        $child = $params['child'];
4152        $parent = $params['parent'];
4153        $pt = $params['paymentTransaction'];
4154        $memberStatus = $params['memberStatus'];
4155
4156        $paymentHash = $pt['payment_hash'];
4157        $ptPassword = $pt['password'];
4158        $ptParams = json_decode($pt['payment_params'], true);
4159
4160        $formType = $ptParams['formType'];
4161        $currencyCode = $ptParams['currencyCode'];
4162        $paymentPlanId = $ptParams['paymentPlanId'];
4163        $priceId = $ptParams['priceId'];
4164        $paymentType = Configure::read('payment_types.payment_receivable');
4165        $platform = $ptParams['platform'];
4166
4167        $membershipStatusIndex = UserTable::getStudentMembershipStatus($child->id);
4168        $currencyId = Configure::read('default.settlement_currency_id'); // set currency id to jpy
4169        $cardCompany = Configure::read('card_company.paypal');
4170        $dateTimeNow = date('Y-m-d H:i:s');
4171
4172        $reservationReceivableAmount = isset($ptParams['reservationReceivableAmount']) ? $ptParams['reservationReceivableAmount'] : 0;
4173        $appreciationReceivableAmount = isset($ptParams['appreciationReceivableAmount']) ? $ptParams['appreciationReceivableAmount'] : 0;
4174        $liveReceivableAmount = isset($ptParams['liveReceivableAmount']) ? $ptParams['liveReceivableAmount'] : 0;
4175
4176
4177        if (!class_exists('PayPal')) {
4178            App::import('Lib', 'PayPal');
4179        }
4180
4181        $PayPal = new PayPal();
4182        $accessTokenData = $PayPal->getAccessToken();
4183
4184        $totalAmount = (int) ($reservationReceivableAmount + $appreciationReceivableAmount + $liveReceivableAmount);
4185
4186        $paypalParams = array(
4187            'ptId' => $pt['id'],
4188            'paypalData' => array('accessTokenData' => $accessTokenData),
4189            'userId' => isset($child->id) ? $child->id : (method_exists($child, 'getId') ? $child->getId() : null),
4190            'money' => $totalAmount,
4191            'formType' => $formType,
4192            'priceId' => $priceId,
4193            'paymentId' => $paymentPlanId,
4194            'paymentType' => $paymentType
4195        );
4196
4197        $receivables = [
4198            'payment_credit_receivable' => $reservationReceivableAmount,
4199            'payment_credit_appreciation_receivable' => $appreciationReceivableAmount,
4200            'payment_live_lesson_receivable' => $liveReceivableAmount
4201        ];
4202
4203        // break if error
4204        if (!isset($accessTokenData['access_token'])) {
4205            $this->log(__METHOD__ . ' paypal error --> ' . json_encode($accessTokenData) . ' --> ' . json_encode($params), $logFileName);
4206            $this->savePaypalFailedSettlement($receivables, $paypalParams);
4207            return;
4208        }
4209
4210        $createOrderParams = array(
4211            'accessToken' => $accessTokenData['access_token'],
4212            'paypalRequestId' => $pt['id'],
4213            'intent' => 'CAPTURE',
4214            'paymentHash' => $paymentHash,
4215            'userId' => $parent->id ?? null,
4216            'currencyCode' => $currencyCode,
4217            'amount' => $totalAmount,
4218            'billingAgreementId' => $parent->paypal_billing_agreement_id ?? null
4219        );
4220
4221        // add mock application code
4222        if (isset($request['mockResponse'])) {
4223            $createOrderParams['mockResponse'] = $request['mockResponse'];
4224        }
4225
4226        $curlPayment = $PayPal->createOrder($createOrderParams);
4227        $paypalParams['paypalData']['createOrder'] = $curlPayment;
4228        $paymentSuccess = isset($curlPayment['status']) && $curlPayment['status'] == 'COMPLETED' ? true : false;
4229
4230        if (!$paymentSuccess) {
4231            $this->log(__METHOD__ . ' paypal error --> ' . json_encode($curlPayment) . ' --> ' . json_encode($params), $logFileName);
4232            $this->savePaypalFailedSettlement($receivables, $paypalParams);
4233            return;
4234        }
4235
4236        // create payment
4237        $savePaymentArr = array(
4238            'user_id' => $child->id,
4239            'amount' => $totalAmount,
4240            'status' => 1,
4241            'reference_id' => $child->id,
4242            'payment_transaction_password' => $ptPassword,
4243            'card_company' => $cardCompany,
4244            'param1' => json_encode($paypalParams),
4245            'form_type' => $formType,
4246            'ordd' => $paymentHash,
4247            'transaction_code' => $paymentHash,
4248            'currency_id' => $currencyId,
4249            'currency_code' => $currencyCode,
4250            'payment_id' => $paymentPlanId,
4251            'price_id' => $priceId,
4252            'payment_type' => $paymentType
4253        );
4254
4255        $this->Payment->clear();
4256        $this->Payment->create();
4257        $this->Payment->set($savePaymentArr);
4258        $this->Payment->validate = array();
4259
4260        // update/add user`s settlement amount
4261        $this->User->updateUserPayments($savePaymentArr);
4262
4263        // set payment_id
4264        $paymentSaveID = $this->Payment->id;
4265        $data = array('payment_id' => $paymentSaveID);
4266        $paymentType = Configure::read('payment_types.payment_receivable');
4267
4268        // reservation receivable
4269        if ($reservationReceivableAmount > 0) {
4270            $savePaymentArr = array(
4271                'user_id' => $child->id,
4272                'amount' => $reservationReceivableAmount,
4273                'status' => 1,
4274                'type_id' => 1,
4275                'reference_id' => $child->id,
4276                'card_company' => $cardCompany,
4277                'param1' => json_encode($data),
4278                'form_type' => Configure::read('payment_credit_receivable'),
4279                'ordd' => $paymentHash,
4280                'transaction_code' => $paymentHash,
4281                'currency_id' => $currencyId,
4282                'currency_code' => $currencyCode,
4283                'payment_id' => $paymentPlanId,
4284                'price_id' => $priceId,
4285                'payment_type' => $paymentType
4286            );
4287
4288            // create new payment for reservation receivable
4289            $this->Payment->clear();
4290            $this->Payment->create();
4291            $this->Payment->set($savePaymentArr);
4292            if (!$this->Payment->save()) {
4293                $this->log(__METHOD__ . ' Failed to save payment data for reservation receivable.' . json_encode($savePaymentArr), $logFileName);
4294                return;
4295            }
4296
4297            // set payment_id
4298            $rrPaymentID = $this->Payment->id;
4299
4300            //update/add user`s settlement amount
4301            $this->User->updateUserPayments($savePaymentArr);
4302
4303            // set payment receivable statuses to 2 - received
4304            $this->PaymentReceivable->updateReceivableReservationPayment(
4305                $child->id,
4306                array(
4307                    'status' => 2,
4308                    'payment_id' => $rrPaymentID,
4309                    'payment_collection_date' => $dateTimeNow,
4310                    'card_company' => $cardCompany,
4311                    'payment_plan_id' => $paymentPlanId,
4312                    'membership_type_index' => $membershipStatusIndex
4313                ),
4314                array(
4315                    'PaymentReceivable.user_id' => $child->id,
4316                    'PaymentReceivable.status' => 0,
4317                    'PaymentReceivable.payment_element_type' => Configure::read('payment_element_type.reservation'),
4318                    'PaymentReceivable.created <=' => $dateTimeNow
4319                )
4320            );
4321        }
4322
4323        // appreciation receivable
4324        if ($appreciationReceivableAmount > 0) {
4325            $savePaymentArr = array(
4326                'user_id' => $child->id,
4327                'amount' => $appreciationReceivableAmount,
4328                'status' => 1,
4329                'type_id' => 1,
4330                'reference_id' => $child->id,
4331                'card_company' => $cardCompany,
4332                'param1' => json_encode($data),
4333                'form_type' => Configure::read('payment_credit_appreciation_receivable'),
4334                'ordd' => $paymentHash,
4335                'transaction_code' => $paymentHash,
4336                'currency_id' => $currencyId,
4337                'currency_code' => $currencyCode,
4338                'payment_id' => $paymentPlanId,
4339                'price_id' => $priceId,
4340                'payment_type' => $paymentType
4341            );
4342
4343            // create new payment for appreciation receivable
4344            $this->Payment->clear();
4345            $this->Payment->create();
4346            $this->Payment->set($savePaymentArr);
4347            if (!$this->Payment->save()) {
4348                $this->log(__METHOD__ . ' Failed to save payment data for appreciation receivable.' . json_encode($savePaymentArr), $logFileName);
4349                return;
4350            }
4351
4352            // set payment_id
4353            $arPaymentID = $this->Payment->id;
4354
4355            //update/add user`s settlement amount
4356            $this->User->updateUserPayments($savePaymentArr);
4357
4358            // set payment receivable statuses to 2 - received
4359            $this->PaymentReceivable->updateReceivableReservationPayment(
4360                $child->id,
4361                array(
4362                    'status' => 2,
4363                    'payment_id' => $arPaymentID,
4364                    'payment_collection_date' => $dateTimeNow,
4365                    'card_company' => $cardCompany,
4366                    'payment_plan_id' => $paymentPlanId,
4367                    'membership_type_index' => $membershipStatusIndex
4368                ),
4369                array(
4370                    'PaymentReceivable.user_id' => $child->id,
4371                    'PaymentReceivable.status' => 0,
4372                    'PaymentReceivable.payment_element_type' => Configure::read('payment_element_type.appreciation'),
4373                    'PaymentReceivable.created <=' => $dateTimeNow
4374                )
4375            );
4376        }
4377
4378        // live receivable
4379        if ($liveReceivableAmount > 0) {
4380            $savePaymentArr = array(
4381                'user_id' => $child->id,
4382                'amount' => $liveReceivableAmount,
4383                'status' => 1,
4384                'type_id' => 1,
4385                'reference_id' => $child->id,
4386                'card_company' => $cardCompany,
4387                'param1' => json_encode($data),
4388                'form_type' => Configure::read('payment_live_lesson_receivable'),
4389                'ordd' => $paymentHash,
4390                'transaction_code' => $paymentHash,
4391                'currency_id' => $currencyId,
4392                'currency_code' => $currencyCode,
4393                'payment_id' => $paymentPlanId,
4394                'price_id' => $priceId,
4395                'payment_type' => $paymentType
4396            );
4397
4398            // create new payment for live receivable
4399            $this->Payment->clear();
4400            $this->Payment->create();
4401            $this->Payment->set($savePaymentArr);
4402            if (!$this->Payment->save()) {
4403                $this->log(__METHOD__ . ' Failed to save payment data for live receivable.' . json_encode($savePaymentArr), $logFileName);
4404                return;
4405            }
4406
4407            // set payment_id
4408            $lrPaymentID = $this->Payment->id;
4409
4410            //update/add user`s settlement amount
4411            $this->User->updateUserPayments($savePaymentArr);
4412
4413            // set payment receivable statuses to 2 - received
4414            $this->PaymentReceivable->updateReceivableReservationPayment(
4415                $child->id,
4416                array(
4417                    'status' => 2,
4418                    'payment_id' => $lrPaymentID,
4419                    'payment_collection_date' => $dateTimeNow,
4420                    'card_company' => $cardCompany,
4421                    'payment_plan_id' => $paymentPlanId,
4422                    'membership_type_index' => $membershipStatusIndex
4423                ),
4424                array(
4425                    'PaymentReceivable.user_id' => $child->id,
4426                    'PaymentReceivable.status' => 0,
4427                    'PaymentReceivable.payment_element_type' => Configure::read('payment_element_type.live'),
4428                    'PaymentReceivable.created <=' => $dateTimeNow
4429                )
4430            );
4431        }
4432
4433        $fields = array('status' => 1);
4434        if (isset($paypalParams)) {
4435            $fields['response_text'] = array('paypal_response' => $paypalParams);
4436        }
4437
4438        // update payment transaction
4439        $this->PaymentTransaction->updateWPPaymentTransaction(array('id' => $ptId ?? null, 'fields' => $fields));
4440
4441        return 'success_order';
4442    }
4443
4444    // ~NJ-29078 - Withdraw Aftee Process Payment
4445    private function processChildAfteePayment($params = array())
4446    {
4447        $logFileName = 'family_plan';
4448        if (
4449            !isset($params['child']) ||
4450            !isset($params['parent']) ||
4451            !isset($params['paymentTransaction'])
4452        ) {
4453            $this->log('__METHOD__' . ' missing parameter(s). --> ' . json_encode($params), $logFileName);
4454            return false;
4455        }
4456
4457        $parent = $params['parent'];
4458        $child = $params['child'];
4459        $pt = $params['paymentTransaction'];
4460
4461        $ptId = $pt['id'];
4462        $ptPassword = $pt['password'] ?? '';
4463        $ptParams = json_decode($pt['payment_params'], true);
4464
4465        $formType = $ptParams['formType'];
4466        $currencyCode = $ptParams['currencyCode'] ?? null;
4467        $paymentPlanId = $ptParams['paymentPlanId'] ?? null;
4468        $priceId = $ptParams['priceId'] ?? null;
4469        $paymentType = $ptParams['paymentType'] ?? null;
4470        $platform = $ptParams['platform'] ?? null;
4471        $paymentHash = $ptParams['orderCode'] ?? null;
4472        $afteeTransactionIdentifier = $ptParams['afteeTransactionIdentifier'] ?? null;
4473
4474        $membershipStatusIndex = UserTable::getStudentMembershipStatus(isset($child->id) ? $child->id : (method_exists($child, 'getId') ? $child->getId() : null));
4475        $currencyId = Configure::read('default.settlement_currency_id'); // set currency id to jpy
4476        $cardCompany = Configure::read('card_company.aftee');
4477        $dateTimeNow = date('Y-m-d H:i:s');
4478
4479        $appreciationFlg = 0;
4480        //$this->log(__METHOD__ . ' aftee debug --> ' . json_encode($params), $logFileName);
4481        // $this->log(__METHOD__ . ' aftee debug --> ' . json_encode($pt), $logFileName);
4482        // $this->log(__METHOD__ . ' aftee debug --> ' . $paymentHash, $logFileName);
4483
4484        // initial aftee amount
4485        $totalAmount = (int)($ptParams['paymentAmount'] ?? 0);
4486        if ($totalAmount > 0) {
4487            if (isset($parent->aftee_transaction_identifier) && !empty($parent->aftee_transaction_identifier)) {
4488                $related_id = $parent->aftee_transaction_identifier;
4489            } else {
4490                $related_id = $afteeTransactionIdentifier;
4491            }
4492
4493            // load PayPal class
4494            if (!class_exists('AfteePaymentService')) {
4495                App::import('Lib', 'AfteePaymentService');
4496            }
4497
4498            $afteeChecksumData = array(
4499                'shopItemId' => "AFTEE" . $formType,
4500                'itemName' => 'FamilyPlanRegistration',
4501                'itemPrice' => $totalAmount,
4502                'itemCount' => 1,
4503                'customerPhoneNumber' => $parent->phone_number,
4504                'customerEmail' => $parent->email,
4505                'shopTransactionNo' => $paymentHash,
4506                'userID' => $parent->id
4507            );
4508            $afteeService = new AfteePaymentService();
4509            $checksum = $afteeService->generateChecksum($afteeChecksumData, false);
4510
4511
4512            $afteeData = array(
4513                'authentication_token' => $parent->card_token,
4514                'related_id' => $related_id,
4515                'checksum' => $checksum['checksum'],
4516                'shop_transaction_no' => $paymentHash,
4517                'transaction_options' => array(1)
4518            );
4519
4520            $afteePaymentData = array_merge($afteeData, $checksum['settlementData']);
4521
4522            // process Aftee direct payment
4523            $res = $afteeService->directPayment($afteePaymentData);
4524            $checkRes = json_decode($res, true);
4525            // $this->log(__METHOD__ . ' aftee --> ' . json_encode($afteePaymentData) . ' --> ' . json_encode($checkRes), $logFileName);
4526
4527            if (isset($checkRes['object']) && $checkRes['object'] == 'transaction') {
4528                $paymentSuccess = true;
4529            } else if (!array_key_exists("object", $checkRes) || (isset($checkRes['object']) && $checkRes['object'] == 'error')) {
4530                $paymentSuccess = false;
4531            }
4532        } else {
4533            // zero payment
4534            $checkRes = array('aftee zero payment --> family plan registration');
4535            $paymentSuccess = true;
4536        }
4537
4538
4539        if (!$paymentSuccess) {
4540            $this->log(__METHOD__ . ' aftee error --> ' . json_encode($checkRes) . ' --> ' . json_encode($params), $logFileName);
4541            return;
4542        }
4543
4544        // payment history data amount
4545        $reservationReceivableAmount = isset($ptParams['reservationReceivableAmount']) ? $ptParams['reservationReceivableAmount'] : 0;
4546        $appreciationReceivableAmount = isset($ptParams['appreciationReceivableAmount']) ? $ptParams['appreciationReceivableAmount'] : 0;
4547        $liveReceivableAmount = isset($ptParams['liveReceivableAmount']) ? $ptParams['liveReceivableAmount'] : 0;
4548
4549        // create payment
4550        $savePaymentArr = array(
4551            'user_id' => $child->id ?? (method_exists($child, 'getId') ? $child->getId() : null),
4552            'status' => 1,
4553            'reference_id' => $child->id ?? (method_exists($child, 'getId') ? $child->getId() : null),
4554            'payment_transaction_password' => $ptPassword,
4555            'card_company' => $cardCompany,
4556            'param1' => json_encode($checkRes),
4557            'form_type' => $formType,
4558            'ordd' => $paymentHash,
4559            'transaction_code' => $paymentHash,
4560            'currency_id' => $currencyId,
4561            'currency_code' => $currencyCode,
4562            'payment_id' => $paymentPlanId,
4563            'price_id' => $priceId,
4564            'payment_type' => $paymentType
4565        );
4566
4567        $this->Payment->clear();
4568        $this->Payment->create();
4569        $this->Payment->set($savePaymentArr);
4570        $this->Payment->validate = array();
4571
4572        // update/add user`s settlement amount
4573        $this->User->updateUserPayments($savePaymentArr);
4574
4575        // set payment_id
4576        $paymentSaveID = $this->Payment->id;
4577        $data = array('payment_id' => $paymentSaveID);
4578        $paymentType = Configure::read('payment_types.payment_receivable');
4579
4580        // reservation receivable
4581        if ($reservationReceivableAmount > 0) {
4582            $savePaymentArr = array(
4583                'user_id' => $child->id,
4584                'amount' => $reservationReceivableAmount,
4585                'status' => 1,
4586                'type_id' => 1,
4587                'reference_id' => $child->id,
4588                'card_company' => $cardCompany,
4589                'param1' => json_encode($data),
4590                'form_type' => Configure::read('payment_credit_receivable'),
4591                'ordd' => $paymentHash,
4592                'transaction_code' => $paymentHash,
4593                'currency_id' => $currencyId,
4594                'currency_code' => $currencyCode,
4595                'payment_id' => $paymentPlanId,
4596                'price_id' => $priceId,
4597                'payment_type' => $paymentType
4598            );
4599
4600            // create new payment for reservation receivable
4601            $this->Payment->clear();
4602            $this->Payment->create();
4603            $this->Payment->set($savePaymentArr);
4604            if (!$this->Payment->save()) {
4605                $this->log(__METHOD__ . ' Failed to save payment data for reservation receivable.' . json_encode($savePaymentArr), $logFileName);
4606                return;
4607            }
4608
4609            // set payment_id
4610            $rrPaymentID = $this->Payment->id;
4611
4612            //update/add user`s settlement amount
4613            $this->User->updateUserPayments($savePaymentArr);
4614
4615            // set payment receivable statuses to 2 - received
4616            $this->PaymentReceivable->updateReceivableReservationPayment(
4617                $child->id,
4618                array(
4619                    'status' => 2,
4620                    'payment_id' => $rrPaymentID,
4621                    'payment_collection_date' => $dateTimeNow,
4622                    'card_company' => $cardCompany,
4623                    'payment_plan_id' => $paymentPlanId,
4624                    'membership_type_index' => $membershipStatusIndex
4625                ),
4626                array(
4627                    'PaymentReceivable.user_id' => $child->id,
4628                    'PaymentReceivable.status' => 0,
4629                    'PaymentReceivable.payment_element_type' => Configure::read('payment_element_type.reservation'),
4630                    'PaymentReceivable.created <=' => $dateTimeNow
4631                )
4632            );
4633        }
4634
4635        // appreciation receivable
4636        if ($appreciationReceivableAmount > 0) {
4637            $savePaymentArr = array(
4638                'user_id' => $child->id,
4639                'amount' => $appreciationReceivableAmount,
4640                'status' => 1,
4641                'type_id' => 1,
4642                'reference_id' => $child->id,
4643                'card_company' => $cardCompany,
4644                'param1' => json_encode($data),
4645                'form_type' => Configure::read('payment_credit_appreciation_receivable'),
4646                'ordd' => $paymentHash,
4647                'transaction_code' => $paymentHash,
4648                'currency_id' => $currencyId,
4649                'currency_code' => $currencyCode,
4650                'payment_id' => $paymentPlanId,
4651                'price_id' => $priceId,
4652                'payment_type' => $paymentType
4653            );
4654
4655            // create new payment for appreciation receivable
4656            $this->Payment->clear();
4657            $this->Payment->create();
4658            $this->Payment->set($savePaymentArr);
4659            if (!$this->Payment->save()) {
4660                $this->log(__METHOD__ . ' Failed to save payment data for appreciation receivable.' . json_encode($savePaymentArr), $logFileName);
4661                return;
4662            }
4663
4664            // set payment_id
4665            $arPaymentID = $this->Payment->id;
4666
4667            //update/add user`s settlement amount
4668            $this->User->updateUserPayments($savePaymentArr);
4669
4670            // set payment receivable statuses to 2 - received
4671            $this->PaymentReceivable->updateReceivableReservationPayment(
4672                $child->id,
4673                array(
4674                    'status' => 2,
4675                    'payment_id' => $arPaymentID,
4676                    'payment_collection_date' => $dateTimeNow,
4677                    'card_company' => $cardCompany,
4678                    'payment_plan_id' => $paymentPlanId,
4679                    'membership_type_index' => $membershipStatusIndex
4680                ),
4681                array(
4682                    'PaymentReceivable.user_id' => $child->id,
4683                    'PaymentReceivable.status' => 0,
4684                    'PaymentReceivable.payment_element_type' => Configure::read('payment_element_type.appreciation'),
4685                    'PaymentReceivable.created <=' => $dateTimeNow
4686                )
4687            );
4688        }
4689
4690        // live receivable
4691        if ($liveReceivableAmount > 0) {
4692            $savePaymentArr = array(
4693                'user_id' => $child->id,
4694                'amount' => $liveReceivableAmount,
4695                'status' => 1,
4696                'type_id' => 1,
4697                'reference_id' => $child->id,
4698                'card_company' => $cardCompany,
4699                'param1' => json_encode($data),
4700                'form_type' => Configure::read('payment_live_lesson_receivable'),
4701                'ordd' => $paymentHash,
4702                'transaction_code' => $paymentHash,
4703                'currency_id' => $currencyId,
4704                'currency_code' => $currencyCode,
4705                'payment_id' => $paymentPlanId,
4706                'price_id' => $priceId,
4707                'payment_type' => $paymentType
4708            );
4709
4710            // create new payment for live receivable
4711            $this->Payment->clear();
4712            $this->Payment->create();
4713            $this->Payment->set($savePaymentArr);
4714            if (!$this->Payment->save()) {
4715                $this->log(__METHOD__ . ' Failed to save payment data for live receivable.' . json_encode($savePaymentArr), $logFileName);
4716                return;
4717            }
4718
4719            // set payment_id
4720            $lrPaymentID = $this->Payment->id;
4721
4722            //update/add user`s settlement amount
4723            $this->User->updateUserPayments($savePaymentArr);
4724
4725            // set payment receivable statuses to 2 - received
4726            $this->PaymentReceivable->updateReceivableReservationPayment(
4727                $child->id,
4728                array(
4729                    'status' => 2,
4730                    'payment_id' => $lrPaymentID,
4731                    'payment_collection_date' => $dateTimeNow,
4732                    'card_company' => $cardCompany,
4733                    'payment_plan_id' => $paymentPlanId,
4734                    'membership_type_index' => $membershipStatusIndex
4735                ),
4736                array(
4737                    'PaymentReceivable.user_id' => $child->id,
4738                    'PaymentReceivable.status' => 0,
4739                    'PaymentReceivable.payment_element_type' => Configure::read('payment_element_type.live'),
4740                    'PaymentReceivable.created <=' => $dateTimeNow
4741                )
4742            );
4743        }
4744
4745        $fields = array('status' => 1);
4746        if (isset($checkRes)) {
4747            $fields['response_text'] = array('aftee' => $checkRes);
4748        }
4749
4750        // update payment transaction
4751        $this->PaymentTransaction->updateWPPaymentTransaction(array('id' => $ptId, 'fields' => $fields));
4752
4753        return 'success_order';
4754    }
4755
4756    /**
4757     * ~NJ-29078 - process child receivable payment 
4758     * @param array $userArr
4759     */
4760    public function processParentReceivablePayment($userArr = [])
4761    {
4762        $logFileName = 'family_plan';
4763        $curlPayment = "";
4764
4765        if (!$pt = $this->Payment->setUpWithdrawTransaction($userArr, $logFileName)) {
4766            return false;
4767        }
4768
4769        if (isset($pt['totalAmount']) && $pt['totalAmount'] == 0) {
4770            $this->log(__METHOD__ . ' No receivable to process' . json_encode($pt), $logFileName);
4771            $curlPayment = "success_order";
4772            return $curlPayment;
4773        }
4774
4775        $userObj = new UserTable($userArr);
4776
4777        if ($userObj->card_company == Configure::read('card_company.zeus')) {
4778            $data = array(
4779                'clientIp' => PaymentTable::getClientIpByCompanyId($userObj->card_company),
4780                'email' => $userObj->email,
4781                'sendId' => $userObj->id,
4782                'money' => $pt['totalAmount'],
4783                'paymentHash' => $pt['payment_hash']
4784            );
4785            // ~process
4786            $curlPayment = $this->ZCharge->charge_with_regsterd_card(json_encode($data));
4787            $curlPayment = PaymentTable::checkPaymentResult($curlPayment);
4788        } else if ($userObj->card_company == Configure::read('card_company.worldpay')) {
4789            $paymentMethodType = myTools::getWPPaymentMethodType($userObj->card_brand, 'payment');
4790            $merchantCode = myTools::getWPMerchantCode($paymentMethodType);
4791            $paymentHash = $pt['payment_hash'];
4792            $paymentMethod = explode('_', $paymentMethodType);
4793            $paymentMethod = isset($paymentMethod[0]) ? $paymentMethod[0] : null;
4794            $currencyExponents = Configure::read('worldpay.currency_exponents');
4795            $exponent = $currencyExponents[$userObj->currency_code];
4796            // get amount with checking currency exponent
4797            $amountArr = myTools::wpGetAmount($exponent, $pt['totalAmount']);
4798            $wpAmount = $amountArr['wpAmount'];
4799
4800            $decodePaymentParams = json_decode($pt['payment_params']);
4801            $paymentFormType = $decodePaymentParams->formType;
4802
4803            $wpParams = array(
4804                'merchantCode' => $merchantCode,
4805                'orderCode' => $paymentHash,
4806                'description' => 'Child Withdrawal Receivables',
4807                'currencyCode' => $userObj->currency_code,
4808                'exponent' => $exponent,
4809                'amount' => $wpAmount,
4810                'cardToken' => $userObj->card_token,
4811                'email' => $userObj->email,
4812                'authenticatedShopperId' => $userObj->id,
4813                'xmlName' => 'direct_payment_with_token',
4814                'shopperIpAddress' => $_SERVER["REMOTE_ADDR"],
4815                'wpTransactionIdentifier' => $userObj->wp_transaction_identifier,
4816                'paymentMethod' => $paymentMethod
4817            );
4818
4819            $updateData = array(
4820                'id' => $pt['id'],
4821                'fields' => array('payment_params' => $wpParams)
4822            );
4823
4824            if (!$this->PaymentTransaction->updateWPPaymentTransaction($updateData)) {
4825                $this->log(__METHOD__ . ' Failed to update payment transaction' . json_encode($updateData), $logFileName);
4826            } else {
4827                if (!$pt = $this->PaymentTransaction->getWPPaymentTransaction($paymentHash)) {
4828                    return false;
4829                }
4830            }
4831
4832            // ~process
4833            $res = wpPaymentService::directPayment($wpParams);
4834
4835            $updateData = array(
4836                'id' => $pt['id'],
4837                'fields' => array('response_text' => array('directPayment_response' => $res))
4838            );
4839
4840            if (!$this->PaymentTransaction->updateWPPaymentTransaction($updateData)) {
4841                $this->log(__METHOD__ . ' Failed to update payment transaction' . json_encode($updateData), $logFileName);
4842            }
4843
4844            if (!myTools::checkIfWPPaymentResponseIsAuthorised($res)) {
4845                $curlPayment = "";
4846                $this->log(__METHOD__ . ' Not authorised payment worldpay' . $userObj->id, $logFileName);
4847            } else {
4848                $this->log(__METHOD__ . ' Worldpay payment response --> ' . json_encode($res), 'error');
4849                $curlPayment = "success_order";
4850            }
4851        } else if ($userObj->card_company == Configure::read('card_company.aftee')) {
4852            $paymentMethodType = myTools::getWPPaymentMethodType($userObj->card_brand, 'payment');
4853            $merchantCode = myTools::getWPMerchantCode($paymentMethodType);
4854            $paymentHash = $pt['payment_hash'];
4855            $paymentMethod = explode('_', $paymentMethodType);
4856            $paymentMethod = isset($paymentMethod[0]) ? $paymentMethod[0] : null;
4857            $decodePaymentParams = json_decode($pt['payment_params']);
4858            $paymentFormType = $decodePaymentParams->formType;
4859
4860            $afteeParams = array(
4861                'merchantCode' => $merchantCode,
4862                'orderCode' => $paymentHash,
4863                'description' => 'Family Plan Registration',
4864                'currencyCode' => $userObj->currency_code,
4865                'amount' => $pt['totalAmount'],
4866                'cardToken' => $userObj->card_token,
4867                'email' => $userObj->email,
4868                'authenticatedShopperId' => $userObj->id,
4869                'shopperIpAddress' => $_SERVER["REMOTE_ADDR"],
4870                'afteeTransactionIdentifier' => $userObj->aftee_transaction_identifier,
4871                'paymentMethod' => $paymentMethod
4872            );
4873
4874            $updateData = array(
4875                'id' => $pt['id'],
4876                'fields' => array('payment_params' => $afteeParams)
4877            );
4878
4879            if (!$this->PaymentTransaction->updateAfteePaymentTransaction($updateData)) {
4880                $this->log(__METHOD__ . ' Failed to update payment transaction' . json_encode($updateData), $logFileName);
4881            } else {
4882                if (!$pt = $this->PaymentTransaction->getAfteePaymentTransaction($paymentHash)) {
4883                    return false;
4884                }
4885            }
4886
4887            // ~process
4888            $afteeParams = array(
4889                'user' =>  $userObj,
4890                'paymentTransaction' => $pt,
4891                'appreciationFlg' => $userObj->allow_appreciation_flg,
4892                'tipAmount' => myTools::stringToFloat($userObj->tip_max_amount)
4893            );
4894
4895            $curlPayment = $this->processParentAfteePayment($afteeParams);
4896        } elseif ($userObj->card_company == Configure::read('card_company.paypal')) {
4897            $paypalParams = array(
4898                'user' => $userObj,
4899                'paymentTransaction' => $pt,
4900                'memberStatus' => 'exist'
4901            );
4902            $curlPayment = $this->processParentPaypalPayment($paypalParams);
4903            $this->log(__METHOD__ . ' Paypal payment response --> ' . json_encode($curlPayment), 'error');
4904        } else if ($userObj->card_company == Configure::read('card_company.stripe.apple') || $userObj->card_company == Configure::read('card_company.stripe.google')){
4905            if (!class_exists('Stripe')) {
4906                App::import('Lib', 'Stripe');
4907            }
4908
4909            $data = array(
4910                'customerId' => $userObj->stripe_customer_id,
4911                'amount' => $pt['totalAmount'],
4912                'currency' => $userObj->currency_code,
4913                'paymentMethodID' => $userObj->stripe_payment_identifier,
4914                'description' => 'Family Plan Receivable Payment',
4915                'sendpoint' => $pt['payment_hash'],
4916                'sendid' => $userObj->id,
4917                'card_company' => $userObj->card_company
4918            );
4919            
4920            $stripe = new Stripe();
4921            $curlPayment = $stripe->directPayment($data);
4922            // $this->log(__METHOD__ . ' Stripe payment response --> ' . json_encode($curlPayment), 'error');    
4923            $curlPayment = myTools::checkStripePaymentResponse($curlPayment);
4924            // $this->log(__METHOD__ . ' Stripe payment response2 --> ' . json_encode($curlPayment), 'error');    
4925
4926        }
4927
4928        return $curlPayment;
4929    }
4930
4931    // ~NJ-29078 - Withdraw Paypal Process Payment
4932    private function processParentPaypalPayment($params = array())
4933    {
4934        $logFileName = 'family_plan';
4935        if (
4936            !isset($params['user']) ||
4937            !isset($params['paymentTransaction'])
4938        ) {
4939            $this->log('__METHOD__' . ' missing parameter(s). --> ' . json_encode($params), $logFileName);
4940            return false;
4941        }
4942
4943        // ~check for family parent 
4944        $user = $params['user'];
4945        $pt = $params['paymentTransaction'];
4946        $memberStatus = $params['memberStatus'];
4947        $paymentHash = $pt['payment_hash'] ?? null;
4948        $ptPassword = $pt['password'] ?? '';
4949        $ptParams = json_decode($pt['payment_params'] ?? '', true);
4950
4951        $formType = $ptParams['formType'] ?? null;
4952        $currencyCode = $ptParams['currencyCode'] ?? null;
4953        $paymentPlanId = $ptParams['paymentPlanId'] ?? null;
4954        $priceId = $ptParams['priceId'] ?? null;
4955        $paymentType = Configure::read('payment_types.payment_receivable');
4956        $platform = $ptParams['platform'] ?? null;
4957
4958        $membershipStatusIndex = UserTable::getStudentMembershipStatus(method_exists($user, 'getId') ? $user->getId() : (isset($user->id) ? $user->id : null));
4959        $currencyId = Configure::read('default.settlement_currency_id'); // set currency id to jpy
4960        $cardCompany = Configure::read('card_company.paypal');
4961        $dateTimeNow = date('Y-m-d H:i:s');
4962
4963        $reservationReceivableAmount = isset($ptParams['reservationReceivableAmount']) ? $ptParams['reservationReceivableAmount'] : 0;
4964        $appreciationReceivableAmount = isset($ptParams['appreciationReceivableAmount']) ? $ptParams['appreciationReceivableAmount'] : 0;
4965        $liveReceivableAmount = isset($ptParams['liveReceivableAmount']) ? $ptParams['liveReceivableAmount'] : 0;
4966
4967
4968        if (!class_exists('PayPal')) {
4969            App::import('Lib', 'PayPal');
4970        }
4971
4972        $PayPal = new PayPal();
4973        $accessTokenData = $PayPal->getAccessToken();
4974
4975        $totalAmount = (int) ($reservationReceivableAmount + $appreciationReceivableAmount + $liveReceivableAmount);
4976
4977        $paypalParams = array(
4978            'ptId' => $pt['id'],
4979            'paypalData' => array('accessTokenData' => $accessTokenData),
4980            'userId' => method_exists($user, 'getId') ? $user->getId() : ($user->id ?? null),
4981            'money' => $totalAmount,
4982            'formType' => $formType,
4983            'priceId' => $priceId,
4984            'paymentId' => $paymentPlanId,
4985            'paymentType' => $paymentType
4986        );
4987
4988        $receivables = [
4989            'payment_credit_receivable' => $reservationReceivableAmount,
4990            'payment_credit_appreciation_receivable' => $appreciationReceivableAmount,
4991            'payment_live_lesson_receivable' => $liveReceivableAmount
4992        ];
4993
4994        // break if error
4995        if (!isset($accessTokenData['access_token'])) {
4996            $this->log(__METHOD__ . ' paypal error --> ' . json_encode($accessTokenData) . ' --> ' . json_encode($params), $logFileName);
4997            $this->savePaypalFailedSettlement($receivables, $paypalParams);
4998            return;
4999        }
5000
5001        $createOrderParams = array(
5002            'accessToken' => $accessTokenData['access_token'],
5003            'paypalRequestId' => $pt['id'],
5004            'intent' => 'CAPTURE',
5005            'paymentHash' => $paymentHash,
5006            'userId' => $user->id ?? null,
5007            'currencyCode' => $currencyCode,
5008            'amount' => $totalAmount,
5009            'billingAgreementId' => $user->paypal_billing_agreement_id ?? null
5010        );
5011
5012        // add mock application code
5013        if (isset($request['mockResponse'])) {
5014            $createOrderParams['mockResponse'] = $request['mockResponse'];
5015        }
5016
5017        $curlPayment = $PayPal->createOrder($createOrderParams);
5018        $paypalParams['paypalData']['createOrder'] = $curlPayment;
5019        $paymentSuccess = isset($curlPayment['status']) && $curlPayment['status'] == 'COMPLETED' ? true : false;
5020
5021        if (!$paymentSuccess) {
5022            //$this->log(__METHOD__ . ' paypal error --> ' . json_encode($curlPayment) . ' --> ' . json_encode($params), $logFileName);
5023            $this->savePaypalFailedSettlement($receivables, $paypalParams);
5024            return;
5025        }
5026
5027        // create payment
5028        $savePaymentArr = array(
5029            'user_id' => $user->id ?? null,
5030            'amount' => $totalAmount,
5031            'status' => 1,
5032            'reference_id' => $user->id ?? null,
5033            'payment_transaction_password' => $ptPassword,
5034            'card_company' => $cardCompany,
5035            'param1' => json_encode($paypalParams),
5036            'form_type' => $formType,
5037            'ordd' => $paymentHash,
5038            'transaction_code' => $paymentHash,
5039            'currency_id' => $currencyId,
5040            'currency_code' => $currencyCode,
5041            'payment_id' => $paymentPlanId,
5042            'price_id' => $priceId,
5043            'payment_type' => $paymentType
5044        );
5045
5046        $this->Payment->clear();
5047        $this->Payment->create();
5048        $this->Payment->set($savePaymentArr);
5049        $this->Payment->validate = array();
5050
5051        // update/add user`s settlement amount
5052        $this->User->updateUserPayments($savePaymentArr);
5053
5054        // set payment_id
5055        $paymentSaveID = $this->Payment->id;
5056        $data = array('payment_id' => $paymentSaveID);
5057        $paymentType = Configure::read('payment_types.payment_receivable');
5058
5059        // reservation receivable
5060        if ($reservationReceivableAmount > 0) {
5061            $savePaymentArr = array(
5062                'user_id' => $user->id,
5063                'amount' => $reservationReceivableAmount,
5064                'status' => 1,
5065                'type_id' => 1,
5066                'reference_id' => $user->id,
5067                'card_company' => $cardCompany,
5068                'param1' => json_encode($data),
5069                'form_type' => Configure::read('payment_credit_receivable'),
5070                'ordd' => $paymentHash,
5071                'transaction_code' => $paymentHash,
5072                'currency_id' => $currencyId,
5073                'currency_code' => $currencyCode,
5074                'payment_id' => $paymentPlanId,
5075                'price_id' => $priceId,
5076                'payment_type' => $paymentType
5077            );
5078
5079            // create new payment for reservation receivable
5080            $this->Payment->clear();
5081            $this->Payment->create();
5082            $this->Payment->set($savePaymentArr);
5083            if (!$this->Payment->save()) {
5084                //$this->log(__METHOD__ . ' Failed to save payment data for reservation receivable.' . json_encode($savePaymentArr), $logFileName);
5085                return;
5086            }
5087
5088            // set payment_id
5089            $rrPaymentID = $this->Payment->id;
5090
5091            //update/add user`s settlement amount
5092            $this->User->updateUserPayments($savePaymentArr);
5093
5094            // set payment receivable statuses to 2 - received
5095            $this->PaymentReceivable->updateReceivableReservationPayment(
5096                $user->id,
5097                array(
5098                    'status' => 2,
5099                    'payment_id' => $rrPaymentID,
5100                    'payment_collection_date' => $dateTimeNow,
5101                    'card_company' => $cardCompany,
5102                    'payment_plan_id' => $paymentPlanId,
5103                    'membership_type_index' => $membershipStatusIndex
5104                ),
5105                array(
5106                    'PaymentReceivable.user_id' => $user->id,
5107                    'PaymentReceivable.status' => 0,
5108                    'PaymentReceivable.payment_element_type' => Configure::read('payment_element_type.reservation'),
5109                    'PaymentReceivable.created <=' => $dateTimeNow
5110                )
5111            );
5112        }
5113
5114        // appreciation receivable
5115        if ($appreciationReceivableAmount > 0) {
5116            $savePaymentArr = array(
5117                'user_id' => $user->id,
5118                'amount' => $appreciationReceivableAmount,
5119                'status' => 1,
5120                'type_id' => 1,
5121                'reference_id' => $user->id,
5122                'card_company' => $cardCompany,
5123                'param1' => json_encode($data),
5124                'form_type' => Configure::read('payment_credit_appreciation_receivable'),
5125                'ordd' => $paymentHash,
5126                'transaction_code' => $paymentHash,
5127                'currency_id' => $currencyId,
5128                'currency_code' => $currencyCode,
5129                'payment_id' => $paymentPlanId,
5130                'price_id' => $priceId,
5131                'payment_type' => $paymentType
5132            );
5133
5134            // create new payment for appreciation receivable
5135            $this->Payment->clear();
5136            $this->Payment->create();
5137            $this->Payment->set($savePaymentArr);
5138            if (!$this->Payment->save()) {
5139                $this->log(__METHOD__ . ' Failed to save payment data for appreciation receivable.' . json_encode($savePaymentArr), $logFileName);
5140                return;
5141            }
5142
5143            // set payment_id
5144            $arPaymentID = $this->Payment->id;
5145
5146            //update/add user`s settlement amount
5147            $this->User->updateUserPayments($savePaymentArr);
5148
5149            // set payment receivable statuses to 2 - received
5150            $this->PaymentReceivable->updateReceivableReservationPayment(
5151                $user->id,
5152                array(
5153                    'status' => 2,
5154                    'payment_id' => $arPaymentID,
5155                    'payment_collection_date' => $dateTimeNow,
5156                    'card_company' => $cardCompany,
5157                    'payment_plan_id' => $paymentPlanId,
5158                    'membership_type_index' => $membershipStatusIndex
5159                ),
5160                array(
5161                    'PaymentReceivable.user_id' => $user->id,
5162                    'PaymentReceivable.status' => 0,
5163                    'PaymentReceivable.payment_element_type' => Configure::read('payment_element_type.appreciation'),
5164                    'PaymentReceivable.created <=' => $dateTimeNow
5165                )
5166            );
5167        }
5168
5169        // live receivable
5170        if ($liveReceivableAmount > 0) {
5171            $savePaymentArr = array(
5172                'user_id' => $user->id,
5173                'amount' => $liveReceivableAmount,
5174                'status' => 1,
5175                'type_id' => 1,
5176                'reference_id' => $user->id,
5177                'card_company' => $cardCompany,
5178                'param1' => json_encode($data),
5179                'form_type' => Configure::read('payment_live_lesson_receivable'),
5180                'ordd' => $paymentHash,
5181                'transaction_code' => $paymentHash,
5182                'currency_id' => $currencyId,
5183                'currency_code' => $currencyCode,
5184                'payment_id' => $paymentPlanId,
5185                'price_id' => $priceId,
5186                'payment_type' => $paymentType
5187            );
5188
5189            // create new payment for live receivable
5190            $this->Payment->clear();
5191            $this->Payment->create();
5192            $this->Payment->set($savePaymentArr);
5193            if (!$this->Payment->save()) {
5194                $this->log(__METHOD__ . ' Failed to save payment data for live receivable.' . json_encode($savePaymentArr), $logFileName);
5195                return;
5196            }
5197
5198            // set payment_id
5199            $lrPaymentID = $this->Payment->id;
5200
5201            //update/add user`s settlement amount
5202            $this->User->updateUserPayments($savePaymentArr);
5203
5204            // set payment receivable statuses to 2 - received
5205            $this->PaymentReceivable->updateReceivableReservationPayment(
5206                $user->id,
5207                array(
5208                    'status' => 2,
5209                    'payment_id' => $lrPaymentID,
5210                    'payment_collection_date' => $dateTimeNow,
5211                    'card_company' => $cardCompany,
5212                    'payment_plan_id' => $paymentPlanId,
5213                    'membership_type_index' => $membershipStatusIndex
5214                ),
5215                array(
5216                    'PaymentReceivable.user_id' => $user->id,
5217                    'PaymentReceivable.status' => 0,
5218                    'PaymentReceivable.payment_element_type' => Configure::read('payment_element_type.live'),
5219                    'PaymentReceivable.created <=' => $dateTimeNow
5220                )
5221            );
5222        }
5223
5224        $fields = array('status' => 1);
5225        if (isset($paypalParams)) {
5226            $fields['response_text'] = array('paypal_response' => $paypalParams);
5227        }
5228
5229        // update payment transaction
5230        $this->PaymentTransaction->updateWPPaymentTransaction(array('id' => $ptId ?? null, 'fields' => $fields));
5231        return 'success_order';
5232    }
5233
5234    private function savePaypalFailedSettlement($receivables = array(), $paypalParams = array()) {
5235        if ($receivables && $paypalParams) {
5236            foreach ($receivables as $configKey => $amount) {
5237                if ($amount > 0) {
5238                    $paypalParams['formType'] = Configure::read($configKey);
5239                    $paypalParams['money'] = $amount;
5240                    
5241                    $this->Payment->paypalSaveFailedSettlement($paypalParams);
5242                }
5243            }
5244        }
5245    }
5246
5247    // ~NJ-29078 - Withdraw Aftee Process Payment
5248    private function processParentAfteePayment($params = array())
5249    {
5250        $logFileName = 'family_plan';
5251        if (
5252            !isset($params['user']) ||
5253            !isset($params['paymentTransaction'])
5254        ) {
5255            $this->log('__METHOD__' . ' missing parameter(s). --> ' . json_encode($params), $logFileName);
5256            return false;
5257        }
5258
5259        $user = $params['user'];
5260        $pt = $params['paymentTransaction'];
5261
5262        $ptId = $pt['id'];
5263        $ptPassword = isset($pt['password']) ? $pt['password'] : '';
5264        $ptParams = json_decode($pt['payment_params'], true);
5265
5266        $formType = $ptParams['formType'] ?? null;
5267        $currencyCode = $ptParams['currencyCode'] ?? null;
5268        $paymentPlanId = $ptParams['paymentPlanId'] ?? null;
5269        $priceId = $ptParams['priceId'] ?? null;
5270        $paymentType = $ptParams['paymentType'] ?? null;
5271        $platform = $ptParams['platform'] ?? null;
5272        $paymentHash = $ptParams['orderCode'] ?? null;
5273        $afteeTransactionIdentifier = $ptParams['afteeTransactionIdentifier'] ?? null;
5274
5275        $membershipStatusIndex = UserTable::getStudentMembershipStatus($user->id);
5276        $currencyId = Configure::read('default.settlement_currency_id'); // set currency id to jpy
5277        $cardCompany = Configure::read('card_company.aftee');
5278        $dateTimeNow = date('Y-m-d H:i:s');
5279
5280        $appreciationFlg = 0;
5281        // $this->log(__METHOD__ . ' aftee debug --> ' . json_encode($params), $logFileName);
5282        // $this->log(__METHOD__ . ' aftee debug --> ' . json_encode($pt), $logFileName);
5283        // $this->log(__METHOD__ . ' aftee debug --> ' . $paymentHash, $logFileName);
5284
5285        // initial aftee amount
5286        $totalAmount = (int)($ptParams['paymentAmount'] ?? 0);
5287
5288        if ($totalAmount > 0) {
5289            if (isset($user->aftee_transaction_identifier) && !empty($user->aftee_transaction_identifier)) {
5290                $related_id = $user->aftee_transaction_identifier;
5291            } else {
5292                $related_id = $afteeTransactionIdentifier;
5293            }
5294
5295            // load PayPal class
5296            if (!class_exists('AfteePaymentService')) {
5297                App::import('Lib', 'AfteePaymentService');
5298            }
5299
5300            $afteeChecksumData = array(
5301                'shopItemId' => "AFTEE" . $formType,
5302                'itemName' => 'FamilyPlanRegistration',
5303                'itemPrice' => $totalAmount,
5304                'itemCount' => 1,
5305                'customerPhoneNumber' => $user->phone_number,
5306                'customerEmail' => $user->email,
5307                'shopTransactionNo' => $paymentHash,
5308                'userID' => $user->id
5309            );
5310            $afteeService = new AfteePaymentService();
5311            $checksum = $afteeService->generateChecksum($afteeChecksumData, false);
5312
5313
5314            $afteeData = array(
5315                'authentication_token' => $user->card_token,
5316                'related_id' => $related_id,
5317                'checksum' => $checksum['checksum'],
5318                'shop_transaction_no' => $paymentHash,
5319                'transaction_options' => array(1)
5320            );
5321
5322            $afteePaymentData = array_merge($afteeData, $checksum['settlementData']);
5323
5324            // process Aftee direct payment
5325            $res = $afteeService->directPayment($afteePaymentData);
5326            $checkRes = json_decode($res, true);
5327            //$this->log(__METHOD__ . ' aftee --> ' . json_encode($afteePaymentData) . ' --> ' . json_encode($checkRes), $logFileName);
5328
5329            if (isset($checkRes['object']) && $checkRes['object'] == 'transaction') {
5330                $paymentSuccess = true;
5331            } else if (!array_key_exists("object", $checkRes) || (isset($checkRes['object']) && $checkRes['object'] == 'error')) {
5332                $paymentSuccess = false;
5333            }
5334        } else {
5335            // zero payment
5336            $checkRes = array('aftee zero payment --> family plan registration');
5337            $paymentSuccess = true;
5338        }
5339
5340        if (!$paymentSuccess) {
5341            $this->log(__METHOD__ . ' aftee error --> ' . json_encode($checkRes) . ' --> ' . json_encode($params), $logFileName);
5342            return;
5343        }
5344
5345        // payment history data amount
5346        $reservationReceivableAmount = isset($ptParams['reservationReceivableAmount']) ? $ptParams['reservationReceivableAmount'] : 0;
5347        $appreciationReceivableAmount = isset($ptParams['appreciationReceivableAmount']) ? $ptParams['appreciationReceivableAmount'] : 0;
5348        $liveReceivableAmount = isset($ptParams['liveReceivableAmount']) ? $ptParams['liveReceivableAmount'] : 0;
5349
5350        // create payment
5351        $savePaymentArr = array(
5352            'user_id' => $user->id,
5353            'status' => 1,
5354            'reference_id' => $user->id,
5355            'payment_transaction_password' => $ptPassword,
5356            'card_company' => $cardCompany,
5357            'param1' => json_encode($checkRes),
5358            'form_type' => $formType,
5359            'ordd' => $paymentHash,
5360            'transaction_code' => $paymentHash,
5361            'currency_id' => $currencyId,
5362            'currency_code' => $currencyCode,
5363            'payment_id' => $paymentPlanId,
5364            'price_id' => $priceId,
5365            'payment_type' => $paymentType
5366        );
5367
5368        $this->Payment->clear();
5369        $this->Payment->create();
5370        $this->Payment->set($savePaymentArr);
5371        $this->Payment->validate = array();
5372
5373        // update/add user`s settlement amount
5374        $this->User->updateUserPayments($savePaymentArr);
5375
5376        // set payment_id
5377        $paymentSaveID = $this->Payment->id;
5378        $data = array('payment_id' => $paymentSaveID);
5379        $paymentType = Configure::read('payment_types.payment_receivable');
5380
5381        // reservation receivable
5382        if ($reservationReceivableAmount > 0) {
5383            $savePaymentArr = array(
5384                'user_id' => $user->id,
5385                'amount' => $reservationReceivableAmount,
5386                'status' => 1,
5387                'type_id' => 1,
5388                'reference_id' => $user->id,
5389                'card_company' => $cardCompany,
5390                'param1' => json_encode($data),
5391                'form_type' => Configure::read('payment_credit_receivable'),
5392                'ordd' => $paymentHash,
5393                'transaction_code' => $paymentHash,
5394                'currency_id' => $currencyId,
5395                'currency_code' => $currencyCode,
5396                'payment_id' => $paymentPlanId,
5397                'price_id' => $priceId,
5398                'payment_type' => $paymentType
5399            );
5400
5401            // create new payment for reservation receivable
5402            $this->Payment->clear();
5403            $this->Payment->create();
5404            $this->Payment->set($savePaymentArr);
5405            if (!$this->Payment->save()) {
5406                $this->log(__METHOD__ . ' Failed to save payment data for reservation receivable.' . json_encode($savePaymentArr), $logFileName);
5407                return;
5408            }
5409
5410            // set payment_id
5411            $rrPaymentID = $this->Payment->id;
5412
5413            //update/add user`s settlement amount
5414            $this->User->updateUserPayments($savePaymentArr);
5415
5416            // set payment receivable statuses to 2 - received
5417            $this->PaymentReceivable->updateReceivableReservationPayment(
5418                $user->id,
5419                array(
5420                    'status' => 2,
5421                    'payment_id' => $rrPaymentID,
5422                    'payment_collection_date' => $dateTimeNow,
5423                    'card_company' => $cardCompany,
5424                    'payment_plan_id' => $paymentPlanId,
5425                    'membership_type_index' => $membershipStatusIndex
5426                ),
5427                array(
5428                    'PaymentReceivable.user_id' => $user->id,
5429                    'PaymentReceivable.status' => 0,
5430                    'PaymentReceivable.payment_element_type' => Configure::read('payment_element_type.reservation'),
5431                    'PaymentReceivable.created <=' => $dateTimeNow
5432                )
5433            );
5434        }
5435
5436        // appreciation receivable
5437        if ($appreciationReceivableAmount > 0) {
5438            $savePaymentArr = array(
5439                'user_id' => $user->id,
5440                'amount' => $appreciationReceivableAmount,
5441                'status' => 1,
5442                'type_id' => 1,
5443                'reference_id' => $user->id,
5444                'card_company' => $cardCompany,
5445                'param1' => json_encode($data),
5446                'form_type' => Configure::read('payment_credit_appreciation_receivable'),
5447                'ordd' => $paymentHash,
5448                'transaction_code' => $paymentHash,
5449                'currency_id' => $currencyId,
5450                'currency_code' => $currencyCode,
5451                'payment_id' => $paymentPlanId,
5452                'price_id' => $priceId,
5453                'payment_type' => $paymentType
5454            );
5455
5456            // create new payment for appreciation receivable
5457            $this->Payment->clear();
5458            $this->Payment->create();
5459            $this->Payment->set($savePaymentArr);
5460            if (!$this->Payment->save()) {
5461                $this->log(__METHOD__ . ' Failed to save payment data for appreciation receivable.' . json_encode($savePaymentArr), $logFileName);
5462                return;
5463            }
5464
5465            // set payment_id
5466            $arPaymentID = $this->Payment->id;
5467
5468            //update/add user`s settlement amount
5469            $this->User->updateUserPayments($savePaymentArr);
5470
5471            // set payment receivable statuses to 2 - received
5472            $this->PaymentReceivable->updateReceivableReservationPayment(
5473                $user->id,
5474                array(
5475                    'status' => 2,
5476                    'payment_id' => $arPaymentID,
5477                    'payment_collection_date' => $dateTimeNow,
5478                    'card_company' => $cardCompany,
5479                    'payment_plan_id' => $paymentPlanId,
5480                    'membership_type_index' => $membershipStatusIndex
5481                ),
5482                array(
5483                    'PaymentReceivable.user_id' => $user->id,
5484                    'PaymentReceivable.status' => 0,
5485                    'PaymentReceivable.payment_element_type' => Configure::read('payment_element_type.appreciation'),
5486                    'PaymentReceivable.created <=' => $dateTimeNow
5487                )
5488            );
5489        }
5490
5491        // live receivable
5492        if ($liveReceivableAmount > 0) {
5493            $savePaymentArr = array(
5494                'user_id' => $user->id,
5495                'amount' => $liveReceivableAmount,
5496                'status' => 1,
5497                'type_id' => 1,
5498                'reference_id' => $user->id,
5499                'card_company' => $cardCompany,
5500                'param1' => json_encode($data),
5501                'form_type' => Configure::read('payment_live_lesson_receivable'),
5502                'ordd' => $paymentHash,
5503                'transaction_code' => $paymentHash,
5504                'currency_id' => $currencyId,
5505                'currency_code' => $currencyCode,
5506                'payment_id' => $paymentPlanId,
5507                'price_id' => $priceId,
5508                'payment_type' => $paymentType
5509            );
5510
5511            // create new payment for live receivable
5512            $this->Payment->clear();
5513            $this->Payment->create();
5514            $this->Payment->set($savePaymentArr);
5515            if (!$this->Payment->save()) {
5516                $this->log(__METHOD__ . ' Failed to save payment data for live receivable.' . json_encode($savePaymentArr), $logFileName);
5517                return;
5518            }
5519
5520            // set payment_id
5521            $lrPaymentID = $this->Payment->id;
5522
5523            //update/add user`s settlement amount
5524            $this->User->updateUserPayments($savePaymentArr);
5525
5526            // set payment receivable statuses to 2 - received
5527            $this->PaymentReceivable->updateReceivableReservationPayment(
5528                $user->id,
5529                array(
5530                    'status' => 2,
5531                    'payment_id' => $lrPaymentID,
5532                    'payment_collection_date' => $dateTimeNow,
5533                    'card_company' => $cardCompany,
5534                    'payment_plan_id' => $paymentPlanId,
5535                    'membership_type_index' => $membershipStatusIndex
5536                ),
5537                array(
5538                    'PaymentReceivable.user_id' => $user->id,
5539                    'PaymentReceivable.status' => 0,
5540                    'PaymentReceivable.payment_element_type' => Configure::read('payment_element_type.live'),
5541                    'PaymentReceivable.created <=' => $dateTimeNow
5542                )
5543            );
5544        }
5545
5546        $fields = array('status' => 1);
5547        if (isset($checkRes)) {
5548            $fields['response_text'] = array('aftee' => $checkRes);
5549        }
5550
5551        // update payment transaction
5552        $this->PaymentTransaction->updateWPPaymentTransaction(array('id' => $ptId, 'fields' => $fields));
5553
5554        return 'success_order';
5555    }
5556
5557    protected function checkCompanyIPForSMS($userId) {
5558        $userIp = $_SERVER['REMOTE_ADDR'];
5559        
5560        $this->InhouseIp->openDBReplica();
5561
5562        $checkCompanyIp = $this->InhouseIp->find('first', array(
5563            'conditions' => array(
5564                'ip_address' => $userIp,
5565                'status' => 1
5566            ),
5567        ));
5568
5569        $this->InhouseIp->closeDBReplica();
5570    
5571        if (!empty($checkCompanyIp)) {
5572            $sms_through_flg = array('sms_through_flg' => 1);
5573            $this->User->updateUserById(array('userData' => $sms_through_flg, 'id' => $userId));
5574            return true;
5575        }
5576
5577        return false;
5578    }
5579
5580    protected function setPerMonthSymbol($language = null, $addDivider = false) {
5581        $allowedLanguages = Configure::read('allowed_currencies');
5582
5583        $perMonthSymbol =  __dx('register', 'month', '月');
5584        $dividerCurrencyCode = Configure::read('currency_jpy');
5585        if (in_array($language, $allowedLanguages) && $language == Configure::read('language_ptbr')) {
5586            $dividerCurrencyCode = Configure::read('currency_brl');
5587            $perMonthSymbol =  __d('register', '毎月');
5588        }
5589
5590        if ($addDivider) {
5591            $perMonthSymbol = myTools::getPriceMonthlyDivider($dividerCurrencyCode) . $perMonthSymbol;
5592        }
5593
5594        $this->set('perMonthSymbol', $perMonthSymbol);
5595    }
5596
5597    public function corporateIpRestrictionLogout()
5598    {
5599        $this->Auth->flash(__d("login", "このアカウントは指定された場所でのみ利用可能です"));
5600        $this->Auth->logout();
5601        return $this->redirect(myTools::getUrl() . '/login');
5602    }
5603
5604}